首页 >后端开发 >C++ >为什么循环 8192 个元素的数组会突然减慢我的程序速度?

为什么循环 8192 个元素的数组会突然减慢我的程序速度?

DDD
DDD原创
2024-12-17 04:47:25260浏览

Why Does Looping Over an 8192-Element Array Suddenly Slow Down My Program?

为什么程序在循环 8192 个元素时速度变慢

考虑以下代码片段:

#define SIZE 8192
float img[SIZE][SIZE]; // input image
float res[SIZE][SIZE]; // result of mean filter

int main() {
    // Initialization
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            img[j][i] = (2 * j + i) % 8196;
        }
    }

    // Matrix processing - applying mean filter
    for (int i = 1; i < SIZE - 1; i++) {
        for (int j = 1; j < SIZE - 1; j++) {
            res[j][i] = 0;
            for (int k = -1; k < 2; k++) {
                for (int l = -1; l < 2; l++) {
                    res[j][i] += img[j + l][i + k];
                }
            }
            res[j][i] /= 9;
        }
    }
}

此代码展示性能变化取决于 SIZE 的值,如其执行所示次数:

  • 大小 = 8191:3.44 秒
  • 大小 = 8192:7.20 秒
  • 大小 = 8193:3.18秒

了解问题

执行时间的差异可以归因于一个称为超级对齐的已知问题:

  • 当 SIZE 是 2048 的倍数时(即, 8192 在本例中),以特定模式访问元素会触发效率较低的内存布局。

内存管理

Malloc/free 不直接负责性能差异。

外循环排序

此代码中的另一个关键问题是外循环的顺序。原始代码按列迭代矩阵,而按行迭代对于内存访问效率更高。

解决方案

为了缓解性能问题,外层循环应互换:

    for (int j = 1; j < SIZE - 1; j++) {
        for (int i = 1; i < SIZE - 1; i++) {
            res[j][i] = 0;
            for (int k = -1; k < 2; k++) {
                for (int l = -1; l < 2; l++) {
                    res[j][i] += img[j + l][i + k];
                }
            }
            res[j][i] /= 9;
        }
    }

性能改进

互换外层循环后,性能显着提升:

  • SIZE = 8191: 0.376 秒
  • SIZE = 8192: 0.357 秒
  • 大小 = 8193: 0.351 秒

以上是为什么循环 8192 个元素的数组会突然减慢我的程序速度?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn