2016-07-14 49 views
0

我正在學習基本的數據結構,並且到目前爲止需要展開鏈接列表。我已經寫了一本書,如果我將每個塊中的元素數量最多設置爲一個緩存行的大小,我將從改進的內存位置獲得更好的緩存性能。我對此有兩個問題。展開鏈接列表的最佳塊大小

首先,將其精確地設置爲高速緩存行的大小還是不可分割的較小大小是最佳選擇?

其次,我在this的帖子中發現L1/2/3緩存的行大小是64字節。我只是想確保這適用於所有型號的i7?我有一個2014年中期的MBP,並試圖創建一個最適合我係統的展開鏈表。是否有任何終端命令檢查緩存行大小?

回答

3

展開的鏈接列表中的節點中的元素都被非常快地訪問。
高速緩存行中的字節全部以非常快的速度訪問。

我們可以在這裏看到這個比喻,展開的鏈接列表在那裏將項目壓縮到連續的內存區域,以便讓它們更容易緩存。

要明白爲什麼具有比緩存行更大的節點大小可能會成爲問題,請考慮具有緩存(任何關聯性)的體系結構,只有一行大小爲S
考慮一個展開的鏈接列表,節點大小爲2S
最後,讓我們分析算法

For each node N 
    Let avg = ArithmeticMean(N.items) 
    For i = 0 To N.numerOfItems - 1 
    N.items[i] = avg 

了設置每個項目的值的高速緩存未命中(假設一個完整的節點)中的一個節點到節點的算術平均值。

要計算均值,必須對所有元素進行求和,訪問第一個元素將觸發緩存加載(+1)。在前半部分中,元素從剛剛加載的緩存行中讀取。
只要第二個元素中的第一個元素被訪問,就需要另一個緩存加載,並刷新舊行(+2)。直到節點結束,第二次加載才能完成所有未來的訪問。
一旦我們有了這個意思,前半部分會被後續的緩存加載(+3)再次訪問,後半部分將被重新加載一次(+4)。

算法觸發節點的4次緩存加載。 如果我們使節點的大小爲S並重複分析,我們將看到只需要緩存加載。

使節點比緩存線更小也會這樣做,一些節點可能最終共享相同的線路,但它通常不會受到傷害。 但是,這將使用更多的行數與列表中的元素總數,因爲每個元素都在自己的地址,並且它們不一定靠近在一起。 在極限S = 1我們有一個普通的鏈表。


到目前爲止,所有不太舊的Intel CPU都有64字節的緩存行。
雖然這可以很好地改變。

要查看您的CPU緩存信息,您可以參考此問題:finding L2 cache size in Linux

它歸結爲使用sudo dmidecode -t cache


由於該陣列被用來存儲元件,允許隨機存取這一事實。

對於所有緩存級別infact。