使用" static"初始化数组改变运行时间?

时间:2017-03-18 04:31:12

标签: c arrays gcc

我注意到在使用O3优化进行编译之后,在C中初始化数组的两种不同方式似乎导致了非常不同的运行时间。这是复制这种差异的最小(尽管没有意义)的例子:

alphabet = 'abcdefghijklmnopqrstuvwxyz ' #space added to end
d = 'gikaclmnqrpoxzybdefijstuvw '        #space added to end

encdic = dict(zip(alphabet,d))
decdic = dict(zip(d,alphabet))

def encrypt(plaintext): #note, I removed d since it isn't used
    s=""
    return s.join(encdic.get(c) for c in plaintext)

def decrypt(encrypted): #note, I removed d since it isn't used
    s=""
    return s.join(encdic.get(c) for c in encrypted)

使用 gcc(Ubuntu 5.4.0-6ubuntu1~16.04.4)5.4.0 20160609 编译该程序,并打开O3优化。这个程序需要 0.02s 来完成我的电脑。

现在,将数组初始化从" int更改为[size];" to" static int a [10000];"并保持其他一切相同。再次使用相同的环境和O3优化进行编译。这次,该程序运行约 0.001s

任何人都可以解释为什么会有这样的不同?谢谢!

1 个答案:

答案 0 :(得分:0)

我认为这很大程度上取决于编译器。我的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("%f\n", time);
  getchar();
  return 0;
}