【发布时间】:2015-12-23 13:04:59
【问题描述】:
前几天我在使用 GCC 和“-Ofast”优化标志时遇到了一个奇怪的问题。使用 'gcc -Ofast -o fib1 fib1.c' 编译以下程序。
#include <stdio.h>
int f1(int n) {
if (n < 2) {
return n;
}
int a, b;
a = f1(n - 1);
b = f1(n - 2);
return a + b;
}
int main(){
printf("%d", f1(40));
}
测量执行时间时,结果是:
peter@host ~ $ time ./fib1
102334155
real 0m0.511s
user 0m0.510s
sys 0m0.000s
现在让我们在程序中引入一个全局变量,并使用“gcc -Ofast -o fib2 fib2.c”再次编译。
#include <stdio.h>
int global;
int f1(int n) {
if (n < 2) {
return n;
}
int a, b;
a = f1(n - 1);
b = f1(n - 2);
global = 0;
return a + b;
}
int main(){
printf("%d", f1(40));
}
现在执行时间是:
peter@host ~ $ time ./fib2
102334155
real 0m0.265s
user 0m0.265s
sys 0m0.000s
新的全局变量没有做任何有意义的事情。但是,执行时间上的差异是相当大的。
除了问题 (1) 这种行为的原因是什么之外,如果 (2) 可以在不引入无意义的变量的情况下实现最后的性能,那也是很好的。有什么建议吗?
谢谢 彼得
【问题讨论】:
-
我首先会怀疑是可疑的基准测试方法。
-
一次测量不足以形成统计数据
-
我认为您需要更加严格地进行基准测试。一个简单但简单的改进是修改代码,以便它可以在循环中重复执行测量的代码。让循环在该循环中执行代码一百万次,然后比较这些结果。还要去掉 printf 语句。
-
@KenClement:请稍等一百万秒,然后告诉我们结果。
-
@KenClement 他的观点是,运行一百万次需要半秒钟的代码是不可行的。由于是递归的,代码基本上已经重复运行了。