首頁 >後端開發 >C++ >為什麼我的程式在處理 8192 個元素時會因記憶體存取模式而顯著變慢?

為什麼我的程式在處理 8192 個元素時會因記憶體存取模式而顯著變慢?

Linda Hamilton
Linda Hamilton原創
2024-12-07 08:30:13201瀏覽

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