C语言中乘法居然和加法一样快?

晓南 发布于 2011/06/22 21:04
阅读 8K+
收藏 0

今天我写了一个测试的程序,运行5000000次以下运算,并分别记录时间。

赋值、加法、减法、乘法、除法、与、或、非、异或、左移、右移、比较。

使用的类型有BYTE、long、float、double。

结果是,赋值跟类型有关,由30ms到50ms不等,其他运算任意一种组合的结果都是19ms。

在另一台更好的电脑上测试的结果是赋值是20ms左右,其他运算(不管什么类型)都是14ms。

所以我很质疑以前老师教我们的结论:(1)乘法比加法更慢;(2)赋值比运算更快。

而我的结论是,所有的运算都是一样快,程序要优化的是运算的次数,特别是赋值的次数。

加载中
1
山间

测试这种运算时间通常采用的方法可能是例如下面的样式:

 time_t time_1;
 int i,a,b,c;

 time_1=clock();
 for (i=0;i<N;i++)
 {


//需要测试的执行代码
 }
 time_1=clock()-time_1;
 printf("\n测试时间:%d\n",time_1);

其中测试代码的写法就比较重要了,

如果测试代码只写a+b;那么会被编译器预编译阶段就无情的删除掉。

如果写a=b+c;并且关闭编译器的优化功能,则是能执行的代码。

但a=b+c这个代码编译后至少会编程类似以下的伪汇编代码:

mov eax,b

add eax,c

mov a,eax

本来目的要计算加法指令的时间,实际指令计算了1次加法,另外有2次数据传输,真正计算时间的比重只占了1/3。

故此,测试代码应使用嵌入式汇编的方法,如下形式:

_asm add eax,edx

仅这一句代码,只完成一个加法计算。

到此为止整个测试代码就万事大吉了吗?不,不,还存在更大的问题!

由于1次加法指令时间太短,在纳秒级,所以通常用多次循环的方式来测量总时间,问题在于循环体本身还要占用时间!看一下整个循环体的伪汇编代码:

    mov i,0

loop:

    mov eax,i

    cmp eax,N

    jge end

   //测试代码add eax,edx

   mov eax,i

    add eax,1

   mov i,eax

   jmp loop

以上是整个循环体的伪汇编代码,从循环体开始共有8条指令代码,而真正的计算加法仅是这8条中的1条,比重占1/8。那么这样的测试代码注定测得的时间大多数是循环体用去的时间,而不是测试代码所用时间。

要真正比较准确的计算出指令时间,首先要做的是获得外层循环体自身占用的时间,即测得空循环体需要的时间,然后在之后加入测试代码再次测得时间,两者之差才是真要测试的指令的运行时间。

然而,还有问题。现在计算机都是多任务的,多线程轮流调度将导致计算过程会被多次打断,例如windows操作系统的10ms原则,如果1个计算不能在10ms内完成,将极有可能被其他进程打断,其他进程运行完毕后再次恢复计算进程,这样测得的时间就不光是本程序的指令执行时间,而是多线程同时运行时的计算总时间,就像在食堂轮流打饭一样。并且程序不可能知道计算何时被打断,这种情况下,就算是单单的空循环的时间都会变得有许多差异。还有就是在底层硬件,每次计算的实际时间也是不同的。我们能够做到的,只能是尽力测得一个相对比较的数值。

具体测试代码可以在http://sj256.com获得,本工作室致力于计算机程序设计技术研究,欢迎广大网友共同讨论。

0
红薯
红薯
这种计算现在都一样是一条CPU指令了
Fuz
Fuz
一条指令不代表一样快,因为有不一样多的执行周期
0
晓南
晓南

引用来自“红薯”的答案

这种计算现在都一样是一条CPU指令了

哇,我到现在才知道。谢谢红薯大哥!还有个问题要请教您,我有个DSP处理器,说是8级流水架构1.0GHz的,相当于目前那一款CPU处理器的处理能力? 我一直不相信它会比Core T6600快。

CheckStyle
CheckStyle
人家Focus在数字信号处理上,功能单一
CheckStyle
CheckStyle
DSP和通用处理器,两者没可比性. DSP只适合算特定的东西
红薯
红薯
这我可不懂了,这些理论全交给学校了:)
0
魏涛
魏涛
乘法不就是位运算么?
0
CheckStyle
CheckStyle
确认编译器没优化,没事先给你算好了?
true
true
哈哈,估计被优化了。
0
Fuz
Fuz
按理来说乘法的执行时间应该是大于N倍加法时间的,其中N是数据位长。用C语言,由于汇编器的不同,产生的汇编代码也有效率好坏的差异,至少不能完全精确地反映乘法与加法的执行时间长短。所以这也并不能如楼主所说推导出乘法与加法执行一样快这样的结论。
0
张亦俊
张亦俊
CPU里面有专用的乘法运算器吧
0
雷志伟
雷志伟
把源代码帖出来, 大家同用一份源代码. 在不同的系统, 不同的硬件平台测试看看.
0
袁世超
袁世超
主要是因为编译优化。
0
魏涛
魏涛

如果我没记错的话。。。= =!

数位数到头大。。。

返回顶部
顶部