我注意到在编译 O3 优化后,在 C 中初始化数组的两种不同方法似乎会导致非常不同的运行时间。下面是复制这种差异的最小(尽管毫无意义(示例:
#include <stdio.h>
#include <time.h>
int main(void) {
int i, j, k;
int size=10000;
int a[size];
clock_t time1 = clock();
for (i=0; i<size; i++) {
for (j=0; j<300000; j++) {
for (k=0; k<700000; k++) {
a[i] = j+k;
}
}
}
clock_t time2 = clock();
double time = (double)(time2-time1)/CLOCKS_PER_SEC*1000.0;
printf("%fn", time);
getchar();
return 0;
}
使用 gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4( 5.4.0 20160609 打开 O3 优化编译此程序。该程序大约需要0.02秒才能在我的计算机上完成。
现在,将数组初始化从"int a[size];"更改为"static int a[10000];",并保持其他所有内容相同。再次使用相同的环境和 O3 优化进行编译。这一次,程序运行了大约 0.001 秒。
谁能解释为什么会有这样的不同?谢谢!
我认为这在很大程度上取决于编译器。我的GCC 5.4在静态存在时完全删除了循环,可能是因为它可以确定计算没有副作用("死代码消除"(。由于某种原因,当存在 VLA 时,它无法执行此操作(这是缺少的优化(。
作为旁注,为了可靠地测量性能,您需要防止编译器优化太多。在您的情况下,我建议将数组创建和计算分开,例如
void __attribute__((noinline, noclone)) benchmark(int *a, int size) {
for (i=0; i<size; i++)
for (j=0; j<300000; j++)
for (k=0; k<700000; k++)
a[i] = j+k;
}
int main(void) {
int i, j, k;
int size=10000;
int a[size];
clock_t time1 = clock();
benchmark(a, size);
clock_t time2 = clock();
double time = (double)(time2-time1)/CLOCKS_PER_SEC*1000.0;
printf("%fn", time);
getchar();
return 0;
}