記憶體階層與效能
以上述方式走訪C語言的二維陣列a[i][j]時,若內層迴圈使用j,會比內層使用i更容易變快。其原因為下列何者?
for (i = 0; i < N; i++)
for (j = 0; j < N; j++)
sum += a[i][j];
- A因為是以列為主(row-major)儲存,會依序讀取連續的位址,能有效利用快取行
- B因為編譯器會將迴圈中的加法合併消除,在執行時連計算本身都省略掉
- C因為內層使用j時完全不會參照TLB,不再需要將虛擬位址轉換為實體位址
查看答案與解析
正確答案:A. 因為是以列為主(row-major)儲存,會依序讀取連續的位址,能有效利用快取行
C語言的二維陣列以列為主(row-major)儲存,a[i][0]、a[i][1]……在記憶體上彼此相鄰。內層使用j時會依序讀取連續的位址,因此一次未命中所載入的64位元組快取行,其餘部分也會馬上被用到。內層使用i時,則會每次跳過一整列的距離、零散地讀取位址,在只用到快取行極小一部分時就容易被逐出。TLB仍會持續使用,並非不再需要位址轉換。
- A. 正確。因為讀取連續的位址,所載入的整條快取行都能用上。
- B. 加法不會被省略,無論哪種順序都進行相同的計算。
- C. TLB仍會繼續使用,位址轉換也照常進行。