2017-05-04 79 views
2

假定4字節的自然對齊。加載緩存時的數據對齊

struct Node 
{ 
int data; 
char c_data; 
}; 
int main() { 
int global = 10; 
struct Node N; 
for (register int i = 0; i < 10; i++) 
cout << global << N.data << endl; } 

如果緩存行大小爲16字節,如果我的程序在訪問這些環2個變量,這些變量將如何存在於緩存?假設一切都是寄存器變量。

在同一緩存行?

在不同的緩存行?

如果相同的緩存行,每個成員會在緩存中以4字節對齊的地址開始嗎?像全局變量將跨越[0,3],N將跨越[4,7] ..類似的東西?或者如果結構只有一個字符,它甚至可以從緩存行中的[5]開始。

基本上,在將數據加載到緩存中時,根據結構的大小考慮對齊還是第一個成員?

+0

根據行大小而不是數據大小將數據加載到緩存行中,因此,內存中的數據組織/對齊會反映到緩存中。 – LPs

回答

2

緩存的使用方式主要取決於代碼,這是您在問題中提到但未發佈的理論循環。在循環之前使用的其他變量可能優先,取決於分配在哪裏的變量。即使給出了具體系統的詳細源代碼,也很難確切地知道會發生什麼。

在內存中相鄰分配的變量對緩存友好。基本上,應該有一大塊相鄰分配的變量可以從RAM傳輸到緩存,以便緩存高效。如果你在完全不同的段中有變量,那就會導致「緩存未命中」:也就是說,必須從緩存中拋出某些東西,而其他東西則必須從RAM中讀取。

例如,如果您有一大塊本地堆棧分配的變量,那麼它們全部存儲在緩存中可能會有好處。

在你的情況,global在內存的.data部分被分配和N.bss部分分配的,所以他們是不是在所有相鄰的文件,也不會加載到這個原因,相同的高速緩存行。這意味着就你而言,整個緩存的討論甚至都不適用。

如果改爲寫struct Node N = {1};,那麼它似乎是合理的假設變量,如果在同一個地方在代碼中使用,最終將在.data分配如下(我瘋狂猜測):

4 bytes - global 
4 bytes - N.data 
4 bytes - N.c_data 

其中調整對齊以適應CPU。緩存只是鏡像RAM,沒有任何東西「四處移動以適應對齊」 - 當變量分配到RAM中時,對齊將已經被處理。

這整個塊可能會作爲一個潛在的讀入緩存。

+0

根據你的回答,我修改了問題以保持全局和N爲局部變量。現在我的問題是,無論是全球的還是N的地址都是4的倍數的偏移量?如0,4,8。或者它可以從緩存行的偏移量3,5開始?可能是我在這裏缺少建築知識。請從對齊的角度指導如何將數據拉入並存儲在緩存中。 –

+1

@AnupBuchke如果編譯器/鏈接器將它們放在RAM中對齊的地址上,變量將會對齊。緩存只是RAM的相同副本,包含0到_n_字節的數據。 – Lundin

+0

非常感謝。這有幫助。我將查找鏈接器如何將它們放入RAM中。 –