我正在做简单的测试来衡量程序的执行时间。因此,我编写了一个简单的程序,该程序具有2个循环,每个循环迭代N
次和2N
次。我预计第二个循环大约需要两倍的时间,但是当N=1000000
时结果相反。
我已经对其进行了多次测试,并在另一台机器上获得了相同的结果。为什么会发生?
我的代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
long long sum;
int main(int argc, char **argv)
{
int i;
long elapsed;
struct timeval start, end;
i = atoi(argv[1]);
sum = 0;
gettimeofday(&start, NULL);
while (i--)
sum += i;
gettimeofday(&end, NULL);
elapsed = (end.tv_sec - start.tv_sec) * 1000000;
elapsed += (end.tv_usec - start.tv_usec);
printf("1st loop : %ld\n", elapsed);
i = 2 * atoi(argv[1]);
sum = 0;
gettimeofday(&start, NULL);
while (i--)
sum += i;
gettimeofday(&end, NULL);
elapsed= (end.tv_sec - start.tv_sec) * 1000000;
elapsed+= (end.tv_usec - start.tv_usec);
printf("2nd loop : %ld\n", elapsed);
return 0;
}
一些测试结果
[arch:test] $ ./a.out 10
1st loop : 0
2nd loop : 0
[arch:test] $ ./a.out 100
1st loop : 1
2nd loop : 1
[arch:test] $ ./a.out 1000
1st loop : 7
2nd loop : 14
[arch:test] $ ./a.out 10000
1st loop : 73
2nd loop : 146
[arch:test] $ ./a.out 100000
1st loop : 725
2nd loop : 1448
[arch:test] $ ./a.out 1000000
1st loop : 5369 <-- always greater than 2nd loop
2nd loop : 3536
[arch:test] $ ./a.out 10000000
1st loop : 20203
2nd loop : 34434
[arch:test] $ ./a.out 100000000
1st loop : 174058
2nd loop : 339812
[arch:test] $ ./a.out 1000000000
1st loop : 1709652
2nd loop : 3392287
测试环境
gcc 8.2.1,编译选项-O0
在ubuntu或arch linux上的结果相同,但在Windows 10上使用cygwin的结果相同
答案 0 :(得分:1)
您可能只是碰到了第一个或第二个重新安排,而运行第一个循环的一半首当其冲。 gettimeofday
应该使用实时时钟,因此花费在上下文切换上的时间确实很重要。当您下次运行10次以上的迭代时,上下文切换的次数应增加大约10倍,因此,如果一半的上下文切换次数比另一者多,则平均而言,差异不会太大。
我无法很好地再现您的结果,但是如果我使用time -v
运行可执行文件,因此显示了上下文切换数,则当第一个循环和第二个循环的计时最接近时,上下文切换数为2(第二个上下文切换)。