cpu cache line 原理:blog.csdn.net/zdl1016/article/details/8882092
關(guān)于CPU Cache:cenalulu.github.io/linux/all-about-cpu-cache/
CPU和內(nèi)存的那些事:www.tuicool.com/articles/mUR3Er
關(guān)于cpu的cache:blog.csdn.net/gogdizzy/article/details/9384153
1、cpu的結(jié)構(gòu)


cpu主要包括registers,load/store buffers,L1 cache,L2 cache和多core共享的 L3 cache。
2、各級(jí)存儲(chǔ)的性能

3、cache分類
按功能劃分,緩存可以分為指令緩存(code cache或instruction cache指令緩存)、數(shù)據(jù)緩存(data cache)、TLB緩存(translation lookaside buffer,加速虛擬地址轉(zhuǎn)物理地址)。按速度劃分,當(dāng)前主流CPU都有二級(jí)甚至三級(jí)緩存(分別稱之為L(zhǎng)1,L2,L3)。大部分CPU都把指令緩存和數(shù)據(jù)緩存分開(kāi),以提高性能;也有合并到一起的,降低硬件開(kāi)銷。一般只把數(shù)據(jù)緩存分級(jí)別。
4、cache相關(guān)概念
cache line:每次內(nèi)存和CPU緩存之間交換數(shù)據(jù)都是固定大小,cache line就表示這個(gè)固定的長(zhǎng)度。
cache set:一個(gè)或多個(gè)cache line組成cache set,也叫cache row。
cache entry:緩存條目,包含cache line內(nèi)容(value)和對(duì)應(yīng)的地址(key),可以看做是哈希表中的一項(xiàng)。
cache hit:緩存命中,查找的地址在cache中。
cache miss:緩存未命中,查找的地址不在cache中。
hit rate:命中率,cache hit /(cache hit + cache miss)。
5、cache entry
cache由若干個(gè)cache entry組成(個(gè)人理解),cache entry由以下三部分組成。
tag:包含部分內(nèi)存地址
data block:就是一個(gè)cache line的內(nèi)容
flag bits:一般包含數(shù)據(jù)是否有效(valid bit)和數(shù)據(jù)是否被寫(xiě)(dirty bit),指令緩存因?yàn)橹蛔x,只需要valid bit,但是不知道具體實(shí)現(xiàn)是怎樣的。
6、N-way associative
內(nèi)存數(shù)據(jù)到cache line的映射策略主要有fully associative,Direct Mapped Cache,N-way associative,N-way associative是fully associative和Direct Mapped Cache的折中。N-way associative將cache劃分成2維矩陣,每一行包含N個(gè)cache entry,它們對(duì)應(yīng)的內(nèi)存地址的后幾位都是相同的,可以把cache line想象成hashmap,每一個(gè)hash link有N個(gè)cache line,這N個(gè)cache line組成一個(gè)cache set。
7、內(nèi)存地址到cache的映射
一個(gè)有效內(nèi)存地址可以分為
tag:與cache entry中的tag相同
index:表示裝入cache set的索引號(hào),對(duì)應(yīng)N-way associative的一個(gè)cache set(cache row)。
block offset:表示這個(gè)地址在數(shù)據(jù)塊(data block)中的偏移量
舉例來(lái)說(shuō):
對(duì)于32位地址總線的系統(tǒng),如果L1 cache大小為8k(個(gè)人理解只算了cache line的大?。總€(gè)cache line是64 bytes,4個(gè)cache line組成一個(gè)cache set。那么總共就有8k / 64 bytes = 128個(gè)cache line,每4個(gè)組成一組,那就有128 / 4 = 32個(gè)cache set,所以block offset占6個(gè)bit(2^6=64),index占5個(gè)bit(2^5=32),tag占21個(gè)bit(32 - 5 - 6)。
那么映射過(guò)程(1)根據(jù)內(nèi)存地址中間的5bit計(jì)算出index,找到對(duì)應(yīng)的cache set(2)根據(jù)最前面的21bit計(jì)算出tag,然后遍歷cache set找到對(duì)應(yīng)的cache line(3)根據(jù)內(nèi)存地址最后的6bit計(jì)算出數(shù)據(jù)在cache line中的offset,按照數(shù)據(jù)長(zhǎng)度讀取cache中的數(shù)據(jù)。
8、cpu讀內(nèi)存與cache淘汰策略
cpu從來(lái)都不直接訪問(wèn)內(nèi)存, 都是通過(guò)cache間接訪問(wèn)內(nèi)存,每次訪問(wèn)內(nèi)存時(shí)先查看cache中是否有對(duì)應(yīng)地址的數(shù)據(jù),如果cache中沒(méi)有則先分配一個(gè)cache entry,然后再把內(nèi)存中的數(shù)據(jù)copy到剛剛分配的cache entry的cache line中,再?gòu)腸ache line中讀取數(shù)據(jù)。
cache中包含的cache entry的數(shù)目是有限的,并且遠(yuǎn)小于內(nèi)存,當(dāng)cache entry全部都被占用的時(shí)候,就需要一個(gè)淘汰策略將部分cache entry淘汰掉,一般使用LRU策略。
9、cpu寫(xiě)內(nèi)存與數(shù)據(jù)一致性問(wèn)題
cache中的數(shù)據(jù)更新后,需要回寫(xiě)到內(nèi)存,考慮性能和數(shù)據(jù)一致性,主要有3種回寫(xiě)策略(1)每次更新都回寫(xiě),也叫write-through cache(2)更新后不回寫(xiě),標(biāo)記為dirty,僅當(dāng)cache entry被evict時(shí)才回寫(xiě)(3)更新后,把cache entry送如回寫(xiě)隊(duì)列,待隊(duì)列收集到多個(gè)entry時(shí)批量回寫(xiě)。
有兩種情況可能導(dǎo)致cache中的數(shù)據(jù)過(guò)期(1)DMA,有其他設(shè)備直接更新內(nèi)存的數(shù)據(jù)(2)SMP,同一個(gè)cache line存在多個(gè)CPU各自的cache中,其中一個(gè)CPU對(duì)其進(jìn)行了更新。數(shù)據(jù)同步一般使用MESI協(xié)議和MOESI協(xié)議。
10、超線程技術(shù)
當(dāng)發(fā)生cache miss時(shí)(特別是read cache miss,在cpu運(yùn)行命令時(shí),read只能是同步的,write可以是異步的),cpu在等待數(shù)據(jù)從內(nèi)存讀進(jìn)cache期間,沒(méi)事可做,CPU在硬件層面,把一個(gè)CPU模擬成兩個(gè)CPU,在上層看來(lái)是兩個(gè)CPU,并發(fā)的執(zhí)行兩個(gè)線程.,這樣當(dāng)一個(gè)線程因cache miss在等待時(shí),另一個(gè)線程可以執(zhí)行。
在64位數(shù)據(jù)總線的系統(tǒng)中,只有操作的數(shù)據(jù)小于64bit并且在內(nèi)存中是64bit對(duì)齊且cache在同一個(gè)cache line中才能保證是原子操作,如果cache line大于等于64bit并且是64bit的整數(shù)倍,那么基本可以認(rèn)為在內(nèi)存中是64bit對(duì)齊的數(shù)據(jù)也會(huì)保存在同一個(gè)cache line中,可以認(rèn)為是原子的。
在編碼中盡量利用cache,減少直接訪問(wèn)內(nèi)存,減少多個(gè)共享變量在同一個(gè)cache line中,降低False Sharing現(xiàn)象。