c语言 - 使用"static"更改运行时初始化数组?



我注意到在编译 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;
}

相关内容

最新更新