1. 程式人生 > >for迴圈提高記憶體訪問效率的做法

for迴圈提高記憶體訪問效率的做法

今天寫程式的時候突然想到一點,記錄一下:

計算機記憶體地址是線性排列組織的,而利用for迴圈對高維陣列結構進行遍歷處理的時候,要保證最內層for迴圈遍歷的是高維陣列的最低維度,這樣可以最大化利用CPU的cache,舉個例子:

假設有一個二維影象P(x,y),x為行數,0<=x<=M-1,y為列數,0<=y<=N-1。

若想遍歷影象內所有的畫素,寫程式的時候,有以下兩種巢狀for:

1 for(x=0;x<M;x++){
2     for(y=0;y<N;y++){
3         // ... 
4     }
5 }

1 for(y=0
;y<N;y++){ 2 for(x=0;x<M;x++){ 3 // ... 4 } 5 }

這兩種實現方法都能遍歷影象內畫素,但是第一種效率比第二種高。

因為資料的邏輯形式雖然是高維的,但是儲存在記憶體裡的時候卻仍是以一維線性的方式儲存的,這就造成了高維資料在記憶體中進行表示的時候,最低維的資料在記憶體中被連續儲存,而除最低維以外的其它所有維度在記憶體上是不連續的(對於上述例子,P(3,4)與P(3,5)在記憶體中是連續的,而P(3,4)和P(2,4)在記憶體中就不是連續的),訪問不連續記憶體對於CPU的cache來說很不友好,會造成較大的記憶體訪問延遲,雖然這個問題可能會被聰明的編譯器查到並在編譯時刻優化為cache-friendly的程式碼,但是保不齊有些編譯器沒有這種優化,所以在寫程式的時候還是注意一下這一點。在訪問體素塊的時候最好也要先確定一下資料邏輯形式的最低維度,然後再寫for。