【发布时间】:2018-05-28 11:37:39
【问题描述】:
我正在试验一个程序,看看它的缓存行为是否与我的概念理解一致。
为此,我使用 Perf 命令:
perf stat -e cache-misses ./a.out
记录以下简单C程序的缓存未命中率:
int main() {
int N = 10000;
double *arr = malloc(sizeof(double) * N * N);
for(int i = 0; i < N; i++) {
for(int j = 0; j < N; j++){
arr[i * N + j] = 10.0;
}
}
return 0;
}
我的缓存未命中率为 50.212%。如果我按如下方式更改数组访问模式:
arr[j * N + i]
我知道缓存未命中率为 22.206%。
这些结果让我感到惊讶。
- 50.212% 的缓存未命中率对于这样一个具有非常规则内存访问模式的简单程序来说似乎非常高。我希望这更接近 1/(num-words-per-cache-line) 肯定大于 1/2。为什么缓存未命中率这么高?
- 我对内存的(有限)理解表明,以列优先顺序遍历数组应该会导致更糟糕的缓存行为,但我得到的结果却恰恰相反。发生了什么事?
【问题讨论】:
-
你有什么CPU?
cat /proc/cpuinfo也会告诉你缓存信息。 -
@JonathonReinhart 它是 Intel(R) Xeon(R) CPU,缓存大小为 12288 KB。
-
您生成的程序是否启用了优化?
-
出于好奇,
double (*arr)[N] = malloc( sizeof(double[N][N]) );...arr[i][j] = 10.0会生成更快的代码吗? -
请显示为两个源生成的程序集(GCC 的
-S开关)和您使用的所有编译器开关。 (必须没有启用优化,因为这个程序相当于int main() {}。)perf是从main的开头开始计数,还是在C 运行时启动代码中包含初始化?是否包括指令缓存未命中?
标签: c performance caching memory perf