【发布时间】:2013-11-28 20:27:26
【问题描述】:
我有
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <stdio.h>
#include <math.h>
int fib(int n) {
return n < 2 ? n : fib(n-1) + fib(n-2);
}
double clock_now()
{
struct timeval now;
gettimeofday(&now, NULL);
return (double)now.tv_sec + (double)now.tv_usec/1.0e6;
}
#define NITER 5
在我的main() 中,我正在做一个像这样的简单基准测试:
printf("hi\n");
double t = clock_now();
int f = 0;
double tmin = INFINITY;
for (int i=0; i<NITER; ++i) {
printf("run %i, %f\n", i, clock_now()-t);
t = clock_now();
f += fib(40);
t = clock_now()-t;
printf("%i %f\n", f, t);
if (t < tmin) tmin = t;
t = clock_now();
}
printf("fib,%.6f\n", tmin*1000);
当我使用 clang -O3(来自 Xcode 5.0.1 的 LLVM 5.0)编译时,它总是打印出零时间,除非在 for-loop 的初始化处,即:
hi
run 0, 0.866536
102334155 0.000000
run 1, 0.000001
204668310 0.000000
run 2, 0.000000
307002465 0.000000
run 3, 0.000000
409336620 0.000000
run 4, 0.000001
511670775 0.000000
fib,0.000000
它似乎静态地预先计算fib(40) 并将其存储在某处。正确的?一开始的奇怪延迟(0.8 秒)可能是因为它加载了那个缓存?
我这样做是为了进行基准测试。 C 编译器应尽可能优化fib() 本身。但是,我不希望它在编译时预先计算它。所以基本上我希望所有代码尽可能地优化,但不是main()(或者至少不是这个特定的优化)。我可以这样做吗?
在这种特定情况下,无论如何优化是什么?这有点奇怪,而且相当不错。
【问题讨论】:
-
旁注:
gettimeofday已过时,clock_gettime现在是首选。 -
您可以尝试将代码放在循环中的函数中,该函数将值作为参数传递给调用
fib。 -
@JoachimPileborg:嗯,即使现在可行,也许未来的版本会更聪明,也会优化它,所以这似乎不是一个可靠的解决方案。
-
@Shahbaz 的旁注:Mac OS X 没有
clock_gettime(),因此使用gettimeofday()作为不错的替代代码是正确的。 -
您是否查看了生成的汇编程序,看看是否有任何解释?
标签: c optimization clang