【发布时间】:2019-04-10 19:28:50
【问题描述】:
我正在尝试创建嵌套循环的缓存高效版本。循环的长度使得与循环相关的数据将大于缓存大小。我希望能够在块中迭代循环,以便更有效地使用缓存,但我不知道这是否可能。
我尝试过传统的阻塞方法,但显然这不是循环的正确解决方案,因为 j 每次都从 0 开始迭代。
#define N 65536
#define BLOCK 4096
int min(int a, int b);
int main() {
double a[N];
double d_a;
int i,j;
int bbegin;
int bend;
for(bbegin = 0;bbegin < N;bbegin += BLOCK) {
bend = min(bbegin + BLOCK, N);
for(i=bbegin;i<bend;i++){
for(j=0;j<i;j++){
/* array a has been filled up elsewhere */
d_a = a[i] - a[j];
/* do some stuff with d_a */
}
}
}
}
inline int min(int a, int b) { return (a < b) ? a : b; }
【问题讨论】:
-
对我来说,
gcc 8.3.1为xorl %eax, %eax; ret生成main(),我不确定您希望如何改进这一点。 -
对不起 - 我在这里真的很愚蠢,没有在循环中发布正确的中间部分。
-
缓存大小是多少? “用 d_a 做一些事情”中使用了多少数据?
-
缓存为 32k、64 B、8 路关联。使用 d_a 进行一些计算,并将结果输出到由 i 索引的另一个大小为 N 的数组中。
-
您的
BLOCK太大。在处理一个块时,您将在缓存中有一个由i索引的a块,即4096 个元素,每个元素8 个字节(假设double是8 个字节),它会填满您的缓存。您还将有一个结果块也由i索引,因此还有另外 4096 个元素,每个元素大概有 8 个字节。您将拥有a[j]和一些杂项数据。所以你的BLOCK需要小于当前大小的一半。