【发布时间】:2012-03-30 23:30:49
【问题描述】:
我不知道如何在非常低的级别优化缓存性能,考虑缓存行大小或关联性。这不是你可以在一夜之间学会的东西。考虑到我的程序将在许多不同的系统和架构上运行,我认为无论如何都不值得。但是,总体而言,我可能可以采取一些步骤来减少缓存未命中。
这是我的问题的描述:
我有一个 3d 整数数组,表示空间点的值,例如 [x][y][z]。每个维度都是相同的大小,所以它就像一个立方体。从那我需要创建另一个 3d 数组,其中这个新数组中的每个值都是 7 个参数的函数:原始 3d 数组中的相应值,加上在空间中“触摸”它的 6 个索引。我暂时不担心立方体的棱角。
这就是我在 C++ 代码中的意思:
void process3DArray (int input[LENGTH][LENGTH][LENGTH],
int output[LENGTH][LENGTH][LENGTH])
{
for(int i = 1; i < LENGTH-1; i++)
for (int j = 1; j < LENGTH-1; j++)
for (int k = 1; k < LENGTH-1; k++)
//The for loops start at 1 and stop before LENGTH-1
//or other-wise I'll get out-of-bounds errors
//I'm not concerned with the edges and corners of the
//3d array "cube" at the moment.
{
int value = input[i][j][k];
//I am expecting crazy cache misses here:
int posX = input[i+1] [j] [k];
int negX = input[i-1] [j] [k];
int posY = input[i] [j+1] [k];
int negY = input[i] [j-1] [k];
int posZ = input[i] [j] [k+1];
int negZ = input[i] [j] [k-1];
output [i][j][k] =
process(value, posX, negX, posY, negY, posZ, negZ);
}
}
但是,如果 LENGTH 足够大,当我获取 process 的参数时,我会得到大量的缓存未命中。有没有一种缓存友好的方式来做到这一点,或者有更好的方式来表示我的数据而不是 3d 数组?
如果您有时间回答这些额外的问题,我是否必须考虑 LENGTH 的价值?就像 LENGTH 是 20 vs 100 vs 10000 是不同的。另外,如果我使用整数以外的东西,比如可能是 64 字节的结构,我是否需要做其他事情?
@ildjarn:
抱歉,我认为生成我传递给process3DArray 的数组的代码并不重要。但如果是这样,我想知道为什么。
int main() {
int data[LENGTH][LENGTH][LENGTH];
for(int i = 0; i < LENGTH; i++)
for (int j = 0; j < LENGTH; j++)
for (int k = 0; k < LENGTH; k++)
data[i][j][k] = rand() * (i + j + k);
int result[LENGTH][LENGTH][LENGTH];
process3DArray(data, result);
}
【问题讨论】:
-
“吨”是什么意思?你预计有多少?
-
我真的不知道。我可能会遇到 posX、negX、posY 和 negY 的缓存未命中,但可能不会出现 posZ 和 negZ,因为它们具有更好的局部性。
-
显示调用
process3DArray的代码,特别是为input和output传递的数组是如何分配的。