-
CPU Cache的組織結(jié)構(gòu)
-
Cache與內(nèi)存地址映射
-
直接映射
-
全相聯(lián)映射
-
組相聯(lián)映射
-
-
Cache尋址方式
-
VIVT、VIPT、PIPT(補(bǔ)充)
-
尾語
-
往期推薦
哈嘍,大家好,我是呼嚕嚕,在上一篇文章我們介紹了突破計(jì)算機(jī)性能瓶頸的利器CPU Cache,今天我們來聊聊CPU Cache的組織結(jié)構(gòu)及其它是如何映射與尋址的?
CPU Cache的組織結(jié)構(gòu)
CPU Cache
的組織結(jié)構(gòu):CPU Cache
被劃分成多個組Set
,每個Set
中還可以有多個行Cache Line
,需要注意的是Cache Line是CPU Cache中的基本緩存單位,也有人叫它塊(Block),也就是說它每次讀寫不是一個字節(jié)的去讀寫,而是以Cache Line
為單位,一塊塊地去讀取
一般主流的 CPU 的 Cache Line
大小是64 Byte,當(dāng)然也有其他大小,在Cache塊比較小的時候,這時的命中率很低,隨著塊大小的增加,空間局部性起作用,命中率會快速提高;如下圖:
這種增加趨勢在某一個最佳塊大小處達(dá)到最大值。當(dāng)?shù)竭_(dá)頂峰以后,命中率隨著塊大小的增加反而會逐漸降低。因?yàn)楫?dāng)塊大小非常大時,進(jìn)入Cache中的許多數(shù)據(jù)可能根本用不上,同時隨著塊繼續(xù)增大,時間局部性會逐漸失去作用
而 CPU Line
又由有效標(biāo)志Valid
、標(biāo)志Tag
、數(shù)據(jù)塊Data
這3個部分組成,其中data是真正要來緩存一片連續(xù)內(nèi)存地址中的數(shù)據(jù),而tag是用來查找Cache Line的標(biāo)志,存儲這片連續(xù)數(shù)據(jù)的公共地址,valid表示當(dāng)前緩存的數(shù)據(jù)是否有效,也可以用來協(xié)助查找Cache Line
可以參考下圖:
Cache與內(nèi)存地址映射
我們知道高速緩存的速度要遠(yuǎn)遠(yuǎn)快于主存(內(nèi)存)的速度,但Cache的容量卻是遠(yuǎn)遠(yuǎn)小于主存,相較于主存的價(jià)格,緩存則昂貴的多
另一方面CPU Cache是需要緩存內(nèi)存中的數(shù)據(jù),無論對Cache數(shù)據(jù)讀取還是寫入,CPU都需要知道訪問的內(nèi)存數(shù)據(jù),對應(yīng)于Cache上的哪個位置,而由于Cache容量不夠,無法做到Cache與內(nèi)存地址一一對應(yīng)
那么Cache是如何與內(nèi)存地址進(jìn)行映射的?
其實(shí)CPU Cache
主要有3種的實(shí)現(xiàn)方式:
-
直接映射(direct-mApped),也就是每個 組Set
只有一個Cache Line
,選中Set之后不需要和Set中的每個Line進(jìn)行比對 -
全相連映射(fully associative),即只有一個Set,所以這個Set中包含所有的Line -
組相連映射(set-associative ), 有多個Set,每個Set有多個Line;需要注意的是,組相連也會被稱為路Way,比如6路組相聯(lián),表示每個Set有6個Line
直接映射
直接映射會在內(nèi)存塊和緩存塊之間建立起固定的映射關(guān)系,也就是內(nèi)存中的某個塊總是映射到Cache的一特定塊上
在linux內(nèi)核中,并非總使用基于我們更熟悉的頁來當(dāng)頁緩存。內(nèi)核的早期版本使用了塊緩存,來加速文件系統(tǒng),提高系統(tǒng)性能
我們這里以8塊主存和4塊(行)為例,具體如下圖所示:
通過上圖,我們可以發(fā)現(xiàn)B0塊和B4塊主存只能映射到Cache的第0塊,B3塊和B7塊只能只能映射到Cache的第3塊,其他內(nèi)存塊同理
其實(shí)相當(dāng)于給主存空間按照Cache Line
的大小(也就是Line的行數(shù))來進(jìn)行分區(qū),每個內(nèi)存塊編號需要與Cache Line
的大小取模,得到固定的映射位置即區(qū)內(nèi)編號,映射到與它區(qū)內(nèi)編號相同的Cache Line
上
可以發(fā)現(xiàn)直接映射的優(yōu)點(diǎn):查找效率高,硬件設(shè)備簡單,地址變換速度快,但是它也有缺點(diǎn):由于每個主存塊只有一個固定位置可存放,即使Cache中別的Line空著也不能占用,無法充分利用Cache空間,這樣沖突概率較大
如果沖突了,這多個內(nèi)存塊會不斷地交替裝入固定的映射Cache Line中,導(dǎo)致緩存命中率降低,所以直接映射適合大容量Cache
全相聯(lián)映射
全相聯(lián)映射 主存的數(shù)據(jù)可以放在任意一個Cache line中,映射方式比較靈活,Cache的利用率高,塊沖突的概率低,因?yàn)橹挥挟?dāng)所有的Line都被占滿后才會出現(xiàn)沖突
但是另一方面,訪問緩存時,每次都要和全部Line中的內(nèi)存進(jìn)行比較,速度低延遲高是它無法避免的缺點(diǎn),因此適合于小容量Cache采用
組相聯(lián)映射
組相聯(lián)
映射是直接映射和全相聯(lián)映射的折中方案,吸取2者的優(yōu)點(diǎn),盡量避免2者的缺點(diǎn),組間采用直接映射,組內(nèi)采用全相聯(lián)映射,即主存塊存放到哪個組Set是固定的,存到Set內(nèi)哪一個Cache Line
是靈活隨意的
當(dāng)查找緩存時,不再需要全部進(jìn)行遍歷,只需先查到cache的組號,然后在那一組內(nèi),進(jìn)行小范圍遍歷。這樣沖突概率較小,同時命中率較高,所以這種方式在現(xiàn)代的處理器中得到了廣泛的應(yīng)用
Cache尋址方式
通過前文的閱讀,相信大家都對CPU Cache的組織結(jié)構(gòu)和Cache與內(nèi)存地址映射方式有所了解,而Intel多數(shù)處理器的 L1 Cache 都是32KB,8-Way 組相聯(lián),Cache Line 是 64 Byte
,我們以這個參數(shù)為例,來看看Cache是如何尋址的?
因?yàn)镃ache Line是最小單位(64Bytes),所以可以得出Cache Line的條數(shù) = 32KB /64=512,每一Way的Cache Line條數(shù) = 512 / 8 = 64(也就是每一個Set的Cache Line條數(shù))
那么我們可以得到,每一Set的內(nèi)存大小 = 64 x 64 = 4096B=4KB
,是不是很熟悉,這不正是一個內(nèi)存頁page的大小嘛!本文前面用塊來劃分內(nèi)存,和頁一樣都是內(nèi)存劃分的方式,在操作系統(tǒng)中,頁是固定大小的存儲單元,而塊是可變大小的存儲單元
首先我們得知道內(nèi)存地址如何被分解?內(nèi)存地址被分成了3部分:tag, set index和block offset
-
tag:與Cache Line中的tag匹配,內(nèi)存地址的前24bit -
set index:set索引,用來尋找定位Set,內(nèi)存地址中間的6個bit,正好能查詢2^6=64個line -
block offset:塊偏移量,用來尋找Cache Line里data中的內(nèi)存數(shù)據(jù),內(nèi)存地址最后6位
那么Cache尋址的具體方式,我們可以將其分為3個步驟:
-
先根據(jù)set index來找到對應(yīng)的Set -
接著根據(jù)tag在上一步步找到的set中找到對應(yīng)的 Cache Line
,如果找到且對應(yīng)的有效位valid
為1,表示緩存命中,反之無論其中的tag和Cache Line
里的數(shù)據(jù)內(nèi)容是什么,CPU 都不會管這些數(shù)據(jù),而是會直接訪問主存,重新加載數(shù)據(jù)(當(dāng)然這里涉及到緩存一致性的問題,比較復(fù)雜,先挖個坑,本文暫不講解),那如果沒找到,說明當(dāng)前發(fā)生cache缺失,即cache miss -
最后根據(jù) block offset
在上一步找到的Cache Line的data中找到對應(yīng)內(nèi)存的數(shù)據(jù)
筆者這里再吐血畫了張圖,幫助大家更加直觀了解Cache尋址的具體方式
VIVT、VIPT、PIPT(補(bǔ)充)
最后再介紹一下幾個概念,就是Cache尋址時,可以根據(jù)物理地址,也可以根據(jù)虛擬地址,或者二者結(jié)合起來查找
-
VIVT(Virtually Indexed, Virtually Tagged )表示index和tag都是采用虛擬地址 -
VIPT(Virtually Indexed, Physically Tagged )表示index采用虛擬地址,tag采用物理地址,一般用于 L1 Cache
-
PIPT(Physically Indexed, Physically Tagged )表示index采用物理地址,tag采用物理地址,一般用于 L2 Cache
尾語
本文先后介紹了CPU Cache的組織結(jié)構(gòu),Cache與內(nèi)存地址映射的3種方式,以組相聯(lián)Cache來講解Cache的尋址方式,畫圖太耗心神了,先到這了,后面我們繼續(xù)更新Cache的緩存一致性,提高代碼性能等難點(diǎn)
參考資料:
《Cache: a place for concealment and safekeeping》
https://blog.csdn.NET/qq_38768922/article/detAIls/78737284
http://staff.ustc.edu.cn/~hdrq/jsjzcyl/text/chapter5/sec3/part4/r1.htm