拆分循环和缓存性能

时间:2017-03-09 00:26:18

标签: c++ performance caching

我编写了一些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 的额外访问会以某种方式导致有用的值被驱逐,但是缓存肯定是大到足以容纳这些额外的价值。这可能会发生什么?多个缓存级别是否可能起作用?

此外,欢迎任何有关进一步提高此算法缓存性能的建议,尤其是对相邻行上邻居的访问。

0 个答案:

没有答案