【发布时间】:2013-12-11 09:48:43
【问题描述】:
假设高速缓存行是 64 字节宽,我有两个数组 a 和 b 填充高速缓存行并与高速缓存行对齐。我们还假设两个数组都在 L1 缓存中,所以当我从它们中读取时,我没有缓存未命中。
float a[16]; //64 byte aligned e.g. with __attribute__((aligned (64)))
float b[16]; //64 byte aligned
我读过a[0]。我的问题是现在阅读a[1] 比阅读b[0] 更快吗? 换句话说,从最后使用的缓存行读取是否更快?
设置重要吗?现在让我们假设我有一个 32 kb L1 数据缓存,它是 4 路。因此,如果 a 和 b 相隔 8192 个字节,它们最终会在同一个集合中。这会改变我的问题的答案吗?
另一种提问方式(这是我真正关心的问题)是关于读取矩阵。
换句话说,假设矩阵 M 适合 L1 缓存并且是 64 字节对齐的并且已经在 L1 缓存中,那么这两个代码选项中的哪一个会更有效。
float M[16][16]; //64 byte aligned
版本 1:
for(int i=0; i<16; i++) {
for(int j=0; j<16; j++) {
x += M[i][j];
}
}
版本 2:
for(int i=0; i<16; i++) {
for(int j=0; j<16; j++) {
x += M[j][i];
}
}
编辑:为了说明这一点,由于 SSE/AVX,假设我使用 AVX 一次从 a 读取前八个值(例如使用 _mm256_load_ps())。从a 读取接下来的八个值会比从b 读取前八个值更快吗(回想一下,a 和 b 已经在缓存中,因此不会出现 cahce 未命中)?
编辑::我最感兴趣的是自 Intel Core 2 和 Nehalem 以来的所有处理器,但我目前正在使用 Ivy Bridge 处理器并计划很快使用 Haswell。
【问题讨论】:
标签: c performance optimization x86 cpu-cache