为什么现代的编译器不能在循环中优化行优先顺序访问?

时间:2018-08-08 23:19:37

标签: caching optimization compiler-construction compiler-optimization cache-locality

在教科书Computer Systems: a Programmer's Perspective中,有一些令人印象深刻的基准用于优化行大订单访问。

我创建了一个小程序来测试自己,从行优先访问到列优先访问的简单更改是否会对自己的计算机产生巨大的影响。

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

#define N 30000

int a[N][N] = { 0 };

int main() {
  srand(time(NULL));

  int sum = 0;

  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      a[i][j] = rand() % 99;
    }
  }
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      sum += a[i][j];
    }
  }
}

在我的系统上,平均行主要订单访问进行了8.42sn=5个试验),而列主要订单访问在我的系统上进行了30.12sn=5个试验)这非常重要。

表面上看来,优化起来应该很简单。

现代编译器为什么不优化这些方案?

1 个答案:

答案 0 :(得分:2)

大多数循环不是由简单的sum语句组成,而是在循环迭代之间具有副作用和依赖性。

并非您可以在循环中执行的所有操作都是可交换的,因此优化器将必须真正理解在循环中发生的所有操作,以确保其不会更改其含义,包括任何称为的系统API的内容,动态加载的库中的代码等。

现在这只是一个猜测,但是我希望有人能尝试一下,意识到优化没有足够的信息来运行大多数时间被触发的代码,然后集中精力进行并行执行优化,这是可能在大多数代码库中都有更大的优化机会。