我编写了一些C ++代码来平均2D数组中元素的最近邻值,并将结果写入第二个数组的相应元素。这是迭代多次,每次迭代都会交换grid1和grid2的指针。 yMax和xMax的典型值为~500。我已经编写了这个代码的两个版本,一个代码用于在与差异计算相同的循环中填充grid2,另一个用循环分割:
double difference;
double diffSquared;
for (int i = 0; i < iterations; i++) {
for (int y = 1; y <= yMax + 1; ++y) {
for (int x = 1; x <= xMax + 1; ++x) {
grid2[y][x] = (grid1[y - 1][x] + grid1[y][x + 1] + grid1[y + 1][x] + grid1[y][x - 1])/4.0;
difference = grid1[y][x] - grid2[y][x];
diffSquared += difference*difference;
}
}
*Record difference, then swap grid1 and grid2 pointers*
}
和
double difference;
double diffSquared;
for (int i = 0; i < iterations; i++) {
for (int y = 1; y <= yMax + 1; ++y) {
for (int x = 1; x <= xMax + 1; ++x) {
grid2[y][x] = (grid1[y - 1][x] + grid1[y][x + 1] + grid1[y + 1][x] + grid1[y][x - 1])/4.0;
}
}
for (int y = 1; y <= yMax + 1; ++y) {
for (int x = 1; x <= xMax + 1; ++x) {
difference = grid1[y][x] - grid2[y][x];
diffSquared += difference*difference;
}
}
*Record difference, then swap grid1 and grid2 pointers*
}
打开编译器优化后,代码的第一个版本就会更快。但是,关闭优化(-O0,以g ++为单位),带分割循环的第二个版本可靠得多。我能想到的唯一解释是这与缓存相关,并且对差异和 diffSquared 的额外访问会以某种方式导致有用的值被驱逐,但是缓存肯定是大到足以容纳这些额外的价值。这可能会发生什么?多个缓存级别是否可能起作用?
此外,欢迎任何有关进一步提高此算法缓存性能的建议,尤其是对相邻行上邻居的访问。