与Loop1相比,我期望以下程序中的Loop2花费更多时间。 但即使在启用优化(gcc -O2)后,我发现两个循环几乎都需要相同的时间。为什么在我的系统中使用sizeof(int)= 4和sizeof(short)= 2?我期待编译器将短乘法指令用于乘法短路,从而缩短时间。
#include <stdio.h>
#include <time.h>
float DiffTime(struct timespec Start,struct timespec Stop);
main ()
{
struct timespec start,stop;
int i;
short a,b,c;
int p,q,r;
a=1;
b=2;
c=3;
p=1;
q=2;
r=3;
clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start);
for(i=0;i<1000000;i++) // Loop1
{
a=b*a;
}
clock_gettime (CLOCK_THREAD_CPUTIME_ID, &stop);
printf("Time taken %11.9fs\n",DiffTime(start,stop));
clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start);
for(i=0;i<1000000;i++) // Loop2
{
p=q*p;
}
clock_gettime (CLOCK_THREAD_CPUTIME_ID, &stop);
printf("Time taken %11.9fs\n",DiffTime(start,stop));
printf("%d,%d\n",a,p);
}
float DiffTime(struct timespec Start,struct timespec Stop)
{
long nTime1,nTime2;
nTime1=Start.tv_sec*1000000000 + Start.tv_nsec ;
nTime2=Stop.tv_sec*1000000000 + Stop.tv_nsec ;
return((float)(nTime2-nTime1)/1000000000);
}
答案 0 :(得分:2)
在性能方面,不要指望能够对编译器进行二次猜测。根据您的算法,您唯一应该期待的是更好的大O次。
如果手册中说数据类型的大小是X,那就是它所声称的全部内容,这就是你应该期待的全部内容。
答案 1 :(得分:2)
如果在启用优化后两个循环都为空,我不会感到惊讶。您是否尝试将N增加10倍并查看是否存在差异?
答案 2 :(得分:0)
在大多数32位架构中 - 包含x86 - 乘以16位值需要与32位值相同的时间。 (实际上,它可能会使用完全相同的指令。)
答案 3 :(得分:0)
在大多数硬件平台上,只有一种类型的整数执行单元,它将在相同的CPU周期量下执行与大小无关的整数运算。因此,乘以signed char
,short
,int
,long long int
将需要相同的时间,因为它与执行此操作的硬件相同。
答案 4 :(得分:0)
正如人们已经说过的那样,处理器ALU具有固定的大小,并且会将更小的整数推广到该首选大小。现代处理器至少具有32位ALU。 尚未提及的一点是,在32位或64位机器上,甚至可能发生使用较短类型会产生较慢的代码。由于一些深奥的规则,代码生成器可能需要在某些情况下添加显式符号扩展指令。我在SPARC上使用gcc v3在Solaris上产生了这种影响,它为代码添加了大量16位截断指令,使得短路速度明显慢于使用int。