我正在運行一個內存訪問實驗,其中使用了一個2D矩陣,每行都是內存頁面的大小。實驗包括使用行/列主要讀取每個元素,然後使用行/列主要寫入每個元素。被訪問的矩陣被聲明爲全局範圍,以減輕編程需求。是否比讀取其他值更快地從內存讀取「零」?
這個問題的關鍵在於,在靜態聲明測試矩陣的情況下,編譯器將這些值初始化爲零,我發現結果非常有趣。當我第一次讀取操作時,即
rowMajor_read();
colMajor_read();
rowMajor_write();
colMajor_write();
然後我的colMajor_read操作很快完成。
但是,如果我讀之前做的寫操作,我們有:
rowMajor_write();
colMajor_write();
rowMajor_read();
colMajor_read();
與列主要讀取操作增加幅度近一個數量級。
我認爲它必須與編譯器如何優化代碼有關。由於全局矩陣對於每個元素都是相同的零,編譯器是否完全刪除了讀操作?或者是從某種方式「更容易」從內存中讀取同樣爲零的值?
我沒有通過任何關於優化的特殊編譯器命令,但我確實以這種方式聲明瞭我的函數。
inline void colMajor_read(){
register int row, col;
register volatile char temp __attribute__((unused));
for(col = 0; col < COL_COUNT; col++)
for(row = 0; row < ROW_COUNT; row++)
temp = testArray[row][col];
}
因爲我是運行到編譯器在其中完全除去從上述函數的temp
變量,因爲從來沒有正在使用的問題。我認爲同時擁有volatile
和__attribute__((unused))
是多餘的,但我仍然包括它。我的印象是沒有對易變變量實施優化。
任何想法?
我看着生成的程序集,colMajor_read函數的結果是一樣的。 (彙編)非內聯版本:http://pastebin.com/C8062fYB
我的猜測是系統緩存和預測。 – Nit 2014-10-31 17:24:25
我同意@Nit。緩存局部性很可能是方差的來源。緩存可以輕鬆地提高訪問時間10倍。如果您真的懷疑編譯器優化了遠離操作(不太可能跨功能,但不是絕對不可能),請獲取C函數的彙編程序輸出以檢查。 – 2014-10-31 17:32:02
掛在傢伙身上。我不認爲這一切都很複雜。因爲這些方法是內聯的,這意味着所有這些函數都在同一個編譯單元中,所以編譯器可以做很棒的事情。主要的是,它可以告訴你是否已經改變了自讀寫之後的變量,因此可以很容易地將代碼重新解釋爲'temp = 0;',通過比較它會快得瘋狂。你可以發佈程序集嗎? – IdeaHat 2014-10-31 17:50:03