2008-10-20 68 views
9

今天當我在計算機組織課上時,老師談到了一些有趣的事情。說到爲什麼高速緩存有效,他說:緩存如何工作?

for (i=0; i<M; i++) 
    for(j=0; j<N; j++) 
     X[i][j] = X[i][j] + K; //X is double(8 bytes) 

用第二行改變第一行並不好。你對此有何看法?爲什麼它是這樣的?

+1

這是我在過去幾天看到的第三個基本家庭作業類型的問題。如果你掙扎,你可能想聘請一名導師。 – tvanfosson 2008-10-20 11:45:37

+0

嘿,夥計!這不是功課......我在課堂上偶然發現了這個!因爲老師用中文講,我真的不明白他在說什麼。這就是爲什麼我想問你們所有的...... – israkir 2008-10-20 11:55:03

+2

但是,如果是作業,我可以自己放置'家庭作業'標籤;就像我之前對我最近的一些問題所說的那樣...... – israkir 2008-10-20 11:56:07

回答

9

參考的地點。因爲數據是按行存儲的,所以對於每一行j列都在相鄰的存儲器地址中。操作系統通常會將整個頁面從內存加載到緩存中,並且相鄰的地址引用可能會引用同一頁面。如果通過內部循環中的行索引進行遞增,則這些行可能會位於不同的頁面上(因爲它們之間每隔j個雙重分隔),並且緩存可能必須不斷引入並丟棄內存頁面數據。這被稱爲顛簸,對性能不利。

在實踐中,對於更大,更現代的緩存,行/列的大小需要相當大才能發揮作用,但這仍然是一個好習慣。

[編輯]上面的答案是特定於C,可能會有所不同其他語言。我知道的唯一不同的是FORTRAN。 FORTRAN以列主要順序存儲事物(以上是主行),並且更改FORTRAN中語句的順序是正確的。如果你想/需要效率,瞭解你的語言如何實現數據存儲很重要。

7

這就像是因爲緩存像地方一樣。被訪問的內存數量相同,但間隔更遠,會觸及不同的「緩存行」,甚至可能完全錯過緩存。因此,只要有選擇,組織數據以便可能及時接近彼此的訪問在太空中也是如此。這增加了緩存命中的機會,併爲您提供更多性能。

當然有關於此主題的豐富信息可用,請參閱this wikipedia entry on locality of reference。或者,我猜,你自己的課程教科書。 :)

+0

感謝您的信息。良好的資源;) – israkir 2008-10-20 11:56:42

2

在C中,n維矩陣是主要行,意味着矩陣的最後一個索引表示存儲器中的相鄰空間。這與其他一些語言不同,例如FORTRAN,它們是列主要的。在FORTRAN,它的效率更高,通過二維矩陣像這樣的迭代:

do jj = 1,N 
    do ii = 1,M 
    x(ii,jj) = x(ii,jj) + K; 
    enddo 
enddo 
1

高速緩存是非常快和非常昂貴的內存,坐在靠近CPU。 CPU不是每次從RAM中取一小塊數據,而是獲取一塊數據並將其存儲在緩存中。打賭是,如果你只讀了一個字節,那麼你讀的下一個字節可能就在它之後。如果是這種情況,那麼它可能來自緩存。

通過按照您的循環佈置循環,您可以按照它們存儲在內存中的順序讀取這些字節。這意味着它們在高速緩存中,並且可以由CPU快速讀取。如果在第1行和第2行之間交換,那麼每次在循環中讀取每個「N」個字節。您正在讀取的字節在內存中不再連續,因此它們可能不在緩存中。 CPU必須從(較慢的)RAM中取出它們,所以你的性能會下降。

12

Red Hat的Ulrich Drepper和glibc的名氣很好,What Every Programmer Should Know About Memory。一節詳細討論了緩存。例如,在SMP系統中存在高速緩存效應,其中CPU可能最終顛倒所修改的高速緩存行的所有權,從而極大地損害了性能。