執行緩慢的程式中的記憶體管理困境
當程式迭代特定數量的元素(尤其是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中文網其他相關文章!