首页 >后端开发 >C++ >为什么我的程序在处理 8192 个元素时会因内存访问模式而显着变慢?

为什么我的程序在处理 8192 个元素时会因内存访问模式而显着变慢?

Linda Hamilton
Linda Hamilton原创
2024-12-07 08:30:13207浏览

Why Does My Program Slow Down Significantly When Processing 8192 Elements Due to Memory Access Patterns?

执行缓慢的程序中的内存管理困境

当程序迭代特定数量的元素(尤其是 8192)时,它可能会表现出显着放缓。这种现象源于内存管理,这是一个值得进一步探索的复杂主题。

代码概述

考虑所讨论的循环,它在预定义的矩阵上执行操作:

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

程序的性能差异是由所使用的内存布局类型引起的。访问阵列时,现代处理器更喜欢连续的内存块以获得最佳效率。但是,当循环以非线性方式迭代元素时(如所提供的代码中的情况),处理器在尝试访问非顺序数据时可能会遇到内存停顿。

超级-对齐和缓存问题

问题的症结在于“超对齐”,这是处理器更喜欢访问内存块的现象它们是特定大小的倍数,通常为 16 或 32 字节。在这种情况下,外循环遍历行,而内循环遍历列。当 SIZE 是 2048 的倍数时,外循环会跳过行之间的大部分内存,导致处理器在等待数据时产生延迟。

性能比较

以下执行时间演示了性能影响:

SIZE = 8191: 3.44 secs
SIZE = 8192: 7.20 secs
SIZE = 8193: 3.18 secs

解决方案:重新排序循环

此问题的解决方案是重新排列循环,使外循环迭代列而不是行。这确保了程序访问连续的内存块,消除了导致速度变慢的非顺序访问。

修改后的循环:

for (j = 1; j < SIZE - 1; j++) {
    for (i = 1; i < SIZE - 1; i++) {
        ... (same operations as before) ...
    }
}

通过实现此修改,性能差异消失了,如以下执行时间所示:

SIZE = 8191: 0.376 seconds
SIZE = 8192: 0.357 seconds
SIZE = 8193: 0.351 seconds

以上是为什么我的程序在处理 8192 个元素时会因内存访问模式而显着变慢?的详细内容。更多信息请关注PHP中文网其他相关文章!

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