为什么要学汇编语言(1)

ZivWang 2004-08-24 03:34:40
为什么要学汇编语言?学了之后有什么用?这恐怕是每一个

初学这门语言的人都想知道的问题.

实际上,学习汇编语言,并不一定是要用它来写什么程序,

而是作为一种非常有力的工具----因为它与机器执行的代码

是如此的相近,了解了汇编语言,我们完全可以掌握我们"要"

机器做了什么.这也好比我们用分子原子解释世界,从而知道

燃烧是一种释放能量化学反映而不是由什么神仙或者妖怪的

法力引起的;也好比我们知道万有引力,因此苹果不会飞上天.

下面是www.ytht.net算法版一个朋友提出的问题,我

(Zoologist)和很多人都在解释这个问题,最后.... ....

分作三大部分,分别是提出问题,网友讨论和最后的"真相".

其中,点评是我写的一点看法.下面引用全部是原文,我只是修正

了几个错别字.

1.问题

发信人: gavinbuaa (gavin), 信区: Algorithm
标 题: 请大家帮忙看看这个C++程序,为什么速度相差这么大?
发信站: 一塌糊涂 BBS (Thu Mar 25 17:09:12 2004), 本站(ytht.net)


程序:
#include<stdio.h>
#include<time.h>

#define N 1024 //image size
int i,j,k;
float slice[N][N];

void main()
{
time_t start,end;
float s;
start=time(NULL);

for(k=0;k<100;k++)
{
//省略部分代码
for(j=0;j<N;j++)
for(i=0;i<N;i++)
{
//省略部分代码
slice[i][j]=(float)(slice[i][j]+0.01);
slice[j][i]=(float)(slice[j][i]+0.01);
}
printf("%d\n",k);
}

end=time(NULL);
s=difftime(end,start);
printf(" The total time is %f:",s);
}

编程环境:VC6.0
计算机配置:PIV2.4G,512M

我面临的问题是:当N=1022,1023,1025,1026的时候运行时间都只有s=4秒
左右,可当N=1024的时候,运行时间就是17秒了。后来发现是
“slice[j][i]=(float)(slice[j][i]+0.01);”语句执行速度慢,比
“slice[i][j]=(float)(slice[i][j]+0.01); ”慢2至3倍,也就是说
slice[j][i]比slice[i][j]运行起来慢好多。这是为什么啊?请大家帮帮忙,
我的程序对速度要求很高,越快越好,大家有什么好主意帮我解决这个问题吗?

小弟在这先谢谢大家了!

点评:这里提到的是两个问题,一个是N=1024为什么会慢;另一个是
slice[j][i]和slice[i][j]为什么会有速度上的差别

2."观众"讨论

2.1发信人: yzgd (mice), 信区: Algorithm
标 题: Re: 请大家帮忙看看这个C++程序,为什么速度相差这么大?
发信站: 一塌糊涂 BBS (Fri Mar 26 07:34:22 2004), 本站(ytht.net)

太奇怪了,照理说不会这样。你确定不是程序别的地方的问题吗?我觉得问题出在别处的可能较大。建议你换一个编译器(非VS系列的),再编译一遍试试。

点评:任何时候都要用怀疑的态度来对待问题

2.2发信人: zoologist (王朝), 信区: Algorithm
标 题: Re: 请大家帮忙看看这个C++程序,为什么速度相差这么大?
发信站: 一塌糊涂 BBS (Fri Mar 26 09:39:16 2004), 本站(ytht.net)

说明 Inter C2 667MHZ 128mb win98

Dev-C ++ 4.9.6.0 代码在附件一。

在N=512 耗时 9.00 00 00 00秒
在N=511 耗时 3.00 00 00 00秒
在N=513 耗时 4.00 00 00 00秒

相差很多说明问题确实存在。

首先,研究这个现象,分析生成的可执行

文件。对于上面三个不同值生成的可执行

文件分别命名为 512.exe 511.exe 513.exe

实验发现,如果注释掉

---〉slice[i][j]=(float)(slice[i][j]+0.01); 这条语句,

将不会出现上述情况。


因此,猜测,问题完全是由于这条语句造成的。

在另外一个文件中定义一个数组

{
int a[2][3];
a[0][0]=1; a[0][1]=2; a[0][2]=3;
a[1][0]=4; a[1][1]=5; a[1][2]=6;
return 0;
}

通过观察数组情况发现,存放如下:

a {{1,2,3},{4,5,6}}

(这个是使用tc3观察得到的)

结合上述程序,对比两条语句
for j
for i
{
slice[i][j]=(float)(slice[i][j]+0.01);
slice[j][i]=(float)(slice[j][i]+0.01);
}

猜测如下:

按照 [i][j] i不断变化的访问方式,每一次都需要

跳过大量的数据,也就是说,访问的时候数据不连续。

因此造成前一个语句慢,后一个语句快。

保留 slice[i][j]=(float)(slice[i][j]+0.01);

n=2047 用时 33

保留 slice[j][i]=(float)(slice[j][i]+0.01);

n=2047 用时 26

可以证明上述猜测。

保留 slice[i][j]=(float)(slice[i][j]+0.01);

n=1024 用时 29 n=1025 用时 9

保留 slice[j][i]=(float)(slice[j][i]+0.01);

n=1024 用时 7 n=1025 用时 6

可以看出对于上面语句的影响远大于对下面语句的影响。

因此猜测这个问题是由于cache引起的,但是无法证明。

估计可能是cache大小是按照2的幂次分配的,n=1024

时,正好超过1个(从0到1024是1025个单元)。

附件一:
#include<stdio.h>
#include<time.h>
#include <stdlib.h>
#define N 513 //image size
int i,j,k;
float slice[N][N];

void main()
{
time_t start,end;
float s;
start=time(NULL);

for(k=0;k<100;k++)
{
//省略部分代码
for(j=0;j<N;j++)
for(i=0;i<N;i++)
{
//省略部分代码
slice[i][j]=(float)(slice[i][j]+0.01);
slice[j][i]=(float)(slice[j][i]+0.01);
}
printf("%d\n",k);
}

end=time(NULL);
s=difftime(end,start);
printf(" The total time is %f:",s);
system("PAUSE");
return 0;
}

说明:对于源程序没有多大修改,只是增加最后停止部分。

我对DEV-C不熟悉,之所以用,是因为他小,好装。但是

对于问题应该是没有影响的。因为机器速度慢,所以只能

验证n比较小的情况。

点评:试验一下,发现使用其他编译器同样有这样的问题
...全文
164 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

21,458

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧