1

在教科书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试验),这非常重要。

从表面上看,优化应该是一件非常简单的事情。

为什么现代编译器不优化这些场景?

4

1 回答 1

2

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

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

现在这只是一个猜测,但我希望有人尝试过,意识到优化没有足够的关于正在运行的代码的信息来触发大部分时间,然后专注于并行执行优化,这可能是更大的大多数代码库中的优化机会。

于 2018-08-09T00:36:13.563 回答