cache是個什麼玩意

2021-05-24 06:53:21 字數 4140 閱讀 8949

cachearm920t有16k的資料cache和16k的指令cache,這兩個cache是基本相同的,資料cache多了一些寫回記憶體的機制,後面我們以資料cache為例來介紹cache的基本原理。我們已經知道,cache中的儲存單位是cache line,arm920t的乙個cache line是32位元組,因此16k的cache由512條cache line組成。要了解cache的基本原理,我們從如何設計cache這個問題入手。

設計cache的一種最樸素的想法是,把va分成以32位元組為單位,從任何乙個對齊到32位元組位址邊界的va開始連續的32個位元組(比如0x00-0x1f,0x20-0x3f,0x40-0x5f等等)都可以快取到512條cache line中的任何一條。那麼一條cache line中的32個位元組怎麼知道是來自哪個va的呢?這就需要把va也儲存在cache中,由於這32位元組的起始位址是對齊到32位元組位址邊界的,末5位全為0,因此只需要儲存va[31:5]即可,這稱為va tag[4],tag是va的一部分,是cache line中資料的標識,表明這32位元組資料來自哪個va。這樣設計的cache稱為全相聯cache(fully associative cache),圖示如下:

圖 17. 全相聯cache

給定乙個va,如何在cache中查詢對應的資料呢?首先到cache中比較查詢哪一行的tag等於va[31:5],找到對應的cache line後,再根據va[4:0]決定要訪問的是該cache line快取的32個位元組中的哪乙個位元組。由於有512條cache line,如果這個va沒有快取在cache中則需要比較512次才知道,這是最壞的情況,也是最常見的情況,下面我們要改進cache的設計來解決這個問題。

圖 18. 直接對映cache

位址0~31應該快取在第1條cache line中,位址32~63應該快取在第2條cache line中,依此類推,位址16352~16383應該快取在第512條cache line中,下乙個位址應該是16384(16k)了,我們又回到開頭,位址16k~16k+31應該快取在第1條cache line中,位址16k+32~16k+63應該快取在第2條cache line中,依此類推,再次回到開頭的位址應該是32k,32k~32k+31應該快取在第1條cache line中,32k+32~32k+63應該快取在第2條cache line中,依此類推。讀者應該可以總結出規律了:給定乙個va,將它除以16k得的餘數決定了它應該快取在哪一條cache line中,那麼除以16k的商數部分就應該是va tag,用以區別cache line中快取的到底是0還是16k還是32k位址上的資料。那麼除以16k的商數和餘數怎麼表示呢?va[31:14]就是除以16k的商數,va[13:0]就是餘數,所以上圖的tag處標著va[31:14]。餘數va[13:0]是16k cache裡的乙個位元組偏移量,而cache是按32位元組乙個cache line組織的,所以餘數中的高位va[13:5]決定了是第幾條cache line,餘數中的低位va[4:0]決定了cache line內的位元組偏移量。驗算一下,va[13:5]一共是9位,作為cache line的編號可以表示的cache line數目正是512條。

直接對映cache雖然查詢速度很快,但也有缺點。比如,位址0~31、16k~16k+31、32k~32k+31都應該快取到第1條cache line中,假如我們程式第一次訪問位址30,位址0~31的資料就從記憶體載入到第1條cache line,以便下次訪問能更快一些,但是我們程式第二次訪問的卻是位址32770,位址32k~32k+31的資料就要從記憶體載入到第1條cache line,把cache line裡原來存的位址0~31的資料替換掉,以便下次訪問能更快一些,但是我們程式第三次訪問的卻是位址16392……這樣下去,cache起不到任何加速作用,形同虛設,這種問題稱為cache抖動(cache thrash)。全相聯cache就不會有這種問題,因為任何va都可以快取到任何一條cache line,可以把先後幾次訪問的va快取到不同的cache line,就不會相互衝突。

全相聯cache和直接對映cache各有優缺點,全相聯cache查詢很慢,但沒有抖動問題,直接對映cache則正相反。為了得到更好的效能,實際cpu的cache設計是取兩者的折衷,把所有cache line分成若干個組,每一組有n條cache line,稱為n路組相聯cache(n-way set associative cache)。arm920t採用64路組相聯cache,如下圖所示:

圖 19. 64路組相聯cache

有了前面兩種cache概念的基礎,這種cache應該很好理解,512條cache line分成8組,每組64條,位址0-31、256-587、512-543等等可以快取到第1組64條cache line中的任何一條,位址32-63、288-319、544-575等等可以快取到第2組64條cache line中的任何一條,依此類推。為什麼說組相聯cache是全相聯和直接對映cache的乙個折衷呢?如果把組分得很大,把全部cache line都分到乙個組裡面去,就變成了全相聯cache;如果把組分得很小,每組只有乙個cache line,就變成了直接對映cache。作為練習,請讀者自己計算一下為什麼va tag是va[31:8],為什麼組的編號用va[7:5]表示。

那麼,為什麼組相聯cache的效能比直接對映cache要好呢?一方面,組相聯cache把一條cache line上的衝突分散到了64條cache line上,起到了64倍的積極作用。而另一方面,應該快取到同乙個組的va更多了:對於直接對映cache,在同乙個組(也就是同一條cache line)互相衝突的va有4g/512個;對於組相聯cache,在同乙個組(64條cache line)互相衝突的va有4g/8個。從這個數量關係來看,組相聯cache又起到了64倍的消極作用。難道這兩種作用不會完全抵銷嗎?我不打算從數學上嚴格證明,這不是本節的重點,讀者可以通過乙個生活常識的例子來理解:層數一樣多的兩棟樓,其中一棟樓是一部電梯,每層三戶,而另一棟樓是兩部電梯,每層六戶,每戶的平均人數一樣多,你認為在哪個樓裡等電梯的時間較短呢?

接下來解釋一下有關cache寫回記憶體的問題。cache寫回記憶體有兩種模式:

write back:cache line中的資料被cpu核修改時並不立刻寫回記憶體,cache line和記憶體中的資料會暫時不一致,在cache line中有乙個dirty位標記這一情況。當一條cache line要被其它va的資料替換時,如果不是dirty的就直接替換掉,如果是dirty的就先寫回記憶體再替換。

write through:每當cpu核修改cache line中的資料時就立刻寫回記憶體,cache line和記憶體中的資料總是一致的。如果有多個cpu或裝置同時訪問記憶體,例如採用雙口ram,那麼cache中的資料和記憶體保持一致就非常重要了,這時相關的記憶體頁面通常配置為write through模式。

通過讀寫cp15的相關暫存器,可以對cache做以下操作:

clean:將cache line中的資料寫回記憶體,清除dirty位。在程式中的某些同步點上用於確保cache line和記憶體中的資料一致。

invalidate:在cache line中有乙個invalid位表示無效,將這個位置1,下次要訪問時即使va tag匹配也重新從記憶體讀取資料。例如程序切換時需要宣告前乙個程序快取在cache中的資料無效。

從cache中查詢要訪問的資料時用的是va,但是cache寫回記憶體要用pa,如果寫回記憶體時還需要查一遍頁表就太沒有效率了,所以實際上每條cache line中還儲存了pa[31:5](pa tag),完整的cache構造如下圖所示:

圖 20. pa tag

最後解決我們前面遺留的乙個問題:頁描述符中的c、b位具體是什麼意思?

表 2. 頁描述符中c、b位的含義

c位為1表示允許cache,這種情況下用b位來表示write through還是write back。有些頁面不允許cache,置c位為0,這種情況下可以用b位來選擇是否允許使用write buffer。write buffer也是一種簡單的cache,cpu核執行寫指令時可以把資料交給write buffer,然後由write buffer負責寫回記憶體,這時cpu可以執行後續指令而不必等待寫回記憶體這個較慢的操作結束。想一下,既然有write buffer,為什麼沒有read buffer?

思考與練習

arm920t的cache是64路組相聯的,而pc和伺服器cpu的cache往往只有4路組相聯,路數越多查詢越慢,為什麼arm要設計這麼多的路數?

IT是個什麼玩意

的疑問掐到了關鍵點。但是想解開這個疑問,需要明析it在企業的作用。關於it,不宜分成國企 私企 外企。因為現在國企的競爭意識也挺強。雖然有國家特權資源在手,但也不是守著特權不思進取,而且在人才儲備上非常充裕,資金上也不差,市場意識也不錯,就是既有特權又因為特權而生的種種限制,所以手腳束縛。而外企,雖...

raspberry是個什麼玩意

今天wilson同學取回乙個書本大小的包裹,說買回來一台小電腦,只有信用卡大小!這是第一次聽說和看見raspberry pi。聽說這玩意可以裝linux系統 聽說這玩意是乙個功能齊全的電腦 聽說這玩意可移動網際網路創業者執著地追逐著自己的 硬體夢 想要通過硬體創新改變移動網際網路。務器用 聽說這玩意...

raspberry是個什麼玩意

今天wilson同學取回乙個書本大小的包裹,說買回來一台小電腦,只有信用卡大小!這是第一次聽說和看見raspberry pi。聽說這玩意可以裝linux系統 聽說這玩意是乙個功能齊全的電腦 聽說這玩意可移動網際網路創業者執著地追逐著自己的 硬體夢 想要通過硬體創新改變移動網際網路。務器用 聽說這玩意...