执行缓慢的程序中的内存管理困境
当程序迭代特定数量的元素(尤其是 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中文网其他相关文章!