加法运算和乘法运算的耗时问题

zhuliting 2011-01-10 08:53:37
乘法运算比加法运算复杂,理论上应该更耗时,但我的测试程序却显示,加法比乘法更耗时,请各位帮忙看一下问题出在哪里?谢谢!

windows下代码:
#include <iostream>
#include <time.h>
using namespace std;
const int ITER = 60000;
int main() {
double a, b, s;
clock_t start, end;
a = 1000.011 / 3;
b = 2.011 / 3;
//cout << "a = " << a << ", b = " << b << endl;

start = clock();
for (int i = 0; i < ITER; i++)
for(int j = 0; j < ITER; j++)
{
s = a;
}
end = clock();
cout << "s=a cost: " << end - start << "ms" << endl;

start = clock();
for (int i = 0; i < ITER; i++)
for(int j = 0; j < ITER; j++)
{
s = a + b;
}
end = clock();
cout << "a+b cost: " << end - start << "ms" << endl;

start = clock();
for (int i = 0; i < ITER; i++)
for(int j = 0; j < ITER; j++)
{
s = a * b;
}
end = clock();
cout << "a*b cost: " << end - start << "ms" << endl;
//cout << "CLOCKS_PER_SEC: " << CLOCKS_PER_SEC << endl;
return 0;
}

结果:
s=a cost: 5693ms
a+b cost: 8760ms
a*b cost: 6590ms


Linux下代码:
#include <iostream>
#include <sys/time.h>
using namespace std;
const int ITER = 60000;
int main() {
double a, b, s;
timeval start, end;
double span;
a = 1000.011 / 3;
b = 2.011 / 3;
//cout << "a = " << a << ", b = " << b << endl;
/*gettimeofday(&start, 0);
for (int i = 0; i < ITER; i++)
for (int j = 0; j < ITER; j++);
gettimeofday(&end, 0);
span = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_usec -start.tv_usec) / 1000;
cout << "loop cost: " << span << "ms" << endl;*/

gettimeofday(&start, 0);
for (int i = 0; i < ITER; i++)
for(int j = 0; j < ITER; j++)
{
s = a;
}
gettimeofday(&end, 0);
span = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_usec -start.tv_usec) / 1000;
cout << "s=a cost: " << span << "ms" << endl;

gettimeofday(&start, 0);
for (int i = 0; i < ITER; i++)
for(int j = 0; j < ITER; j++)
{
s = a + b;
}
gettimeofday(&end, 0);
span = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_usec -start.tv_usec) / 1000;
cout << "a+b cost: " << span << "ms" << endl;

gettimeofday(&start, 0);
for (int i = 0; i < ITER; i++)
for(int j = 0; j < ITER; j++)
{
s = a * b;
}
gettimeofday(&end, 0);
span = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_usec -start.tv_usec) / 1000;
cout << "a*b cost: " << span << "ms" << endl;
return 0;
}
结果:
s=a cost: 5453ms
a+b cost: 9461ms
a*b cost: 6772ms
...全文
1577 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
jofranks 2012-08-14
  • 打赏
  • 举报
回复
CPU 的运算器不就是加啊== 当然加法快
zhuliting 2011-02-16
  • 打赏
  • 举报
回复
虽然结论各异,但还是谢谢楼上各位了!
zhuliting 2011-01-20
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 chzhn 的回复:]

什么也不说,给个代码自己测试
C/C++ code

//测试时间1300ms
__declspec(naked) int __stdcall AddTest()
{
__asm
{
push ebp
mov ebp,esp
push esi
push ecx
mov ecx,0x5000000……
[/Quote]

谢谢!
arong1234 2011-01-17
  • 打赏
  • 举报
回复
难道大家都不知道乘法和加法都是单指令周期指令,因此速度一样?
chzhn 2011-01-17
  • 打赏
  • 举报
回复
什么也不说,给个代码自己测试

//测试时间1300ms
__declspec(naked) int __stdcall AddTest()
{
__asm
{
push ebp
mov ebp,esp
push esi
push ecx
mov ecx,0x50000000
xor eax,eax
mov esi,5
Label1:
add eax,esi
dec ecx
test ecx,ecx
jnz Label1
pop ecx
pop esi
mov esp,ebp
pop ebp
retn
}
}

//测试时间0ms
__declspec(naked) int __stdcall MulTest()
{
__asm
{
push ebp
mov ebp,esp
mov eax,5
imul eax,eax,50000000h
mov esp,ebp
pop ebp
retn
}
}
zhuliting 2011-01-17
  • 打赏
  • 举报
回复
还是没明白
jsjygm 2011-01-13
  • 打赏
  • 举报
回复
xwfde 2011-01-12
  • 打赏
  • 举报
回复
实际运行证明,乘法更费时间。
tzg_dzq 2011-01-12
  • 打赏
  • 举报
回复
既然加入了一个乘法器,为什么不加入其他的运算器?
某某9 2011-01-11
  • 打赏
  • 举报
回复
汇编中mul和imul
就是乘法指令吧

当然实质还是加法,
即使减法的实质也是加法
某某9 2011-01-11
  • 打赏
  • 举报
回复
乘法器

一个乘法器大致组成(最简单的真值乘法器,当然不存在真值乘法器,这里以2个正数为例,原码是相对于补码和反码而言)。3个寄存器和一个加法器和逻辑处理电路。



假设我们要计算 4 * 5。他们的原码则是 0100, 0101(注,以4位存贮单元,因为是原码,最高位不代表符号位)。用乘法器大致过程如下:



1. 3个寄存器分别存放乘数0101,被乘数0100和一个部分积(用来暂存部分结果的寄存器),部分积初值为0.



2. 首先判断乘数寄存器(目前值是0101,既为5)的最低位为1.如果为1则将部分积的值通过加法器加上被乘数0100。因此此次步骤结束后,部分积寄存器的内容是0100.



3. 将乘数寄存器右移一位,同时将部分积寄存器也右移一位。同时乘数寄存器最低位溢出丢弃。而部分积寄存器最高位补0(采用算术右移,这里由于是原码,补0即可),部分积寄存器最低位溢出后填充到乘数寄存器。因此,部分积寄存器原来值0100既变成了0010,而最低位的0溢出。乘数寄存器0101,变成了 0|010,最低位0溢出,最高位被部分积溢出的0填充。(注 | 前面是被填充的0,后面是溢出后的乘数,后面都采用这种规则)



4.判断乘数寄存器。最低位为0,不做加法操作。直接执行第3步的移位操作。既有了部分积变成了0001,而乘数变成了00|01.



5.判断乘数寄存器的最低位为1,既采取2,3这2步,部分积0001加上被乘数0100变成了0101,移位后部分积变成了0010,而乘数变成了100|0.



6,判断乘数最低位为0,采取同3相同的步骤。既部分积0010变成了0001,而乘数变成了0100.至此所有乘数全部处理完毕。



最终结果为部分积做高位,乘数寄存器做低位的值 00010100,换成10进制为1 * 2^4 + 1 * 2^2 = 20 = 4 * 5.



处理流程:

1.初始化乘数寄存器,被乘数寄存器和部分积寄存器(0)

2.判断乘数寄存器最低位为1.进入2.1步骤,否则进入步骤3

2.1将部分积+被乘数,结果放到部分积

3.部分积和乘数右移一位。部分积最高位采用算术右移规则。低位溢出到乘数最高位,乘数最低位溢出丢弃。

4.判断乘数乘数是否所有位数都处理,处理完毕则结束,返回结果为部分积+乘数(部分积做高位,乘数做低位,不是简单的算术+)。否则返回到步骤2,循环。



数学原理: 4 * 5 = 100 * 101 = 100 *1 * 2^10 + 100 * 0 * 2^1 + 100 * 1 * 2^0



因为硬件无法表示真值的,最为简单的为原码,既添加一个位做符号位,0为正,负为1.在做乘法时候,符号位单独提出,后面2个数值做乘法运算,再将符号位做一次异或操作既可以得到结果的符号位,添加上即可。关于复杂的补码计算器和更复杂的浮点。有机会再学习。
jsjygm 2011-01-11
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 guandq2106 的回复:]

引用 2 楼 wuyu637 的回复:
http://topic.csdn.net/u/20071106/21/90066a9e-34d3-432e-9264-ac01484aad2c.html

一般来说,乘法比加法耗时,这个已经是定论了。由于cpu的硬件设计决定的。


对于2楼,请查看一下相关资料!
正确解:乘法比加法节省
原因:对于cpu而言,有专门的 乘法器/移位器 运……
[/Quote]
cpu有乘法器?不是都转化成加法做的吗。
管哥的天下 2011-01-11
  • 打赏
  • 举报
回复
已经解决!选择其中的一个按钮,把该按钮选中为缺省按钮!
管哥的天下 2011-01-11
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 wuyu637 的回复:]
http://topic.csdn.net/u/20071106/21/90066a9e-34d3-432e-9264-ac01484aad2c.html

一般来说,乘法比加法耗时,这个已经是定论了。由于cpu的硬件设计决定的。
[/Quote]

对于2楼,请查看一下相关资料!
正确解:乘法比加法节省
原因:对于cpu而言,有专门的 乘法器/移位器 运算单元
evencoming 2011-01-11
  • 打赏
  • 举报
回复
10e次计算。或者更多次计算
zhuliting 2011-01-11
  • 打赏
  • 举报
回复
时间全为0的话,可以把循环开大一些
wuyu637 2011-01-10
  • 打赏
  • 举报
回复
http://topic.csdn.net/u/20071106/21/90066a9e-34d3-432e-9264-ac01484aad2c.html

一般来说,乘法比加法耗时,这个已经是定论了。由于cpu的硬件设计决定的。
wuyu637 2011-01-10
  • 打赏
  • 举报
回复
s=a cost: 0ms
a+b cost: 0ms
a*b cost: 0ms

为啥我的服务器算的都是0.


我觉得你应该考虑一下有没有编译器优化的问题存在,

3,882

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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