基於緩存的存儲器層次結構行之有效,是由於較慢的存儲設備比較快的存儲設備更便宜,還由於程序每每展現局部性:算法
時間局部性:被引用過一次的存儲器的位置極可能在不遠的未來被再次引用。緩存
空間局部性:若是一個存儲器位置被引用了一次,那麼程序極可能在不遠的未來引用附近的一個存儲器位置。spa
一個通用的高速緩存存儲器會有S = 2 ^ s個set(組)操作系統
每一個set含有E個line(既一般所說的cache line)翻譯
每一個line又包含1位vaild bit、 t位tag、B = 2 ^ b bytes cache block(真正存儲數據的地方)。blog
一般咱們說的cache line 64位 32位,其實是說的cache line中cache block是64位32位。索引
假設咱們的存儲器地址有m位,共M = 2^m個不一樣的地址。咱們看一下各個變量之間的關係。進程
cache緩存數據的大小C = (sizeof set * number of set) = (size of block * lines a set) * number of set = B * E * S內存
內存大小2^m Cache line大小2^b 內存的cache line個數2^(m-b)開發
2^(m-b)個cache line分到2^s個set裏, 每一個set會有2^(m - b –s)個cache line,這個數字不是E,是指會有2^(m – b –s)個cache line落到這個set 裏面,那麼就須要有m-b-s位tag,標記出當前是哪一個cache line落到這個set裏面了。也就是說t = m - b –s。
如上圖所示,m位地址的內存,須要s位作索引,選set,t位作tag,選cache line,而後b 位作偏移取具體地址的內存。
高速緩存肯定一個請求是否命中,而後抽取出被請求的字的過程,分爲三步1)組選擇2)行匹配3)字抽取。
直接映射每一個組只有一行E=1
選組
地址中取s bits選組
選行
地址中取t bits與cache line中t bits tag匹配,匹配則命中,不匹配則cache miss
字抽取
地址中的b bits就是cache line中偏移,在命中的cache line中的取字。
直接映射不命中時,不須要什麼策略,直接把索引的組中的cache line替換掉便可。
組相連映射中,一個組包括多個cache line,目前常見的有四路組相連映射,16路組相連映射,即一個set中有4個或16個cache line。對比直接映射,set 個數要比直接映射的少。所以s會小,相應的落到每一個set中的cache line會多,所以t會大。
選組
組相連映射的組選擇與直接映射一致。
選行
cache line的選擇時,由於一個set中有多個cache line,所以須要搜索set中的每一個cache line的tag,對比檢查是否命中。
字抽取
與直接映射一致
組相連映射對於一個index就會有多個行與之相對應,比較每行的tag是否與想要的地址相符合,這樣就會大大增長命中的概率,避免了一小段程序中頻繁cache失效的問題。
組相連映射不命中時,因爲索引到的組中會有多個cache line,所以會有多種算法選擇到底替換哪一個cache line。
全相連映射就是組相連映射只有一個組的狀況。
選組
全相連映射組選擇很簡單,只有一個組,不須要組索引,s = 0,地址只被劃分爲一個標記tag,和一個偏移。
選行
全相連映射cache line選擇時,須要多緩存中的全部cache line進行搜索對比。
字抽取
與以前一致
全相連映射須要大量的搜索cache line進行對比,致使構造一個又大又快的全相連高速緩存很困難,並且很昂貴。所以全相連緩存只適合作小的高速緩存,好比TLB。
以上內容來自《深刻理解計算機系統》6.4
如下內容來自互聯網
邏輯cache,Virtual index virtual tagged是純粹用虛擬地址來尋址,邏輯地址索引邏輯地址tag,這種方式帶來了不少的問題,每一行數據在原有tag的基礎上都要將進程標識加上以區分多個進程之間的相同地址,而在 處理共享內存時也比較麻煩,共享內存在不一樣的進程中的虛擬地址不相同,如何同步是個問題。
物理cache,Physical index physical tagged,物理地址索引和物理地址tag,是一種最容易理解的操做方式,cache針對物理地址進行操做,簡單粗暴,並且不會有歧義。可是這種方式的缺陷也很明顯,在多進程操做系統 中,每一個進程擁有本身獨立的地址空間,指令和代碼都是以虛擬地址的方式存在,cpu發出的memory access的指令都是以虛擬地址的方式發出,這樣的話,對於每個memory access的操做,都要先等待MMU將虛擬地址翻譯爲物理地址,這是一種串行的方式,效率較低。
如今比較多的是採用virtual index physical tagged的方式,virtual index的含義是當cpu發出一個地址請求以後,低位地址去和cache中的index匹配, physical tagged是指虛擬地址的高位地址去和mmu中的頁表匹配以拿到物理地址(index和取物理地址這兩個過程是並行的),而後用從mmu中取到的物理地 址做爲tag(或者tag的一部分)去和cache line的tag位匹配,這樣既保證了同一地址在cache中的惟一性(有個例外,cache alias)又能將mmu和cache並行工做,提升了效率。
這種方式帶來的惟一問題就是cache alias,即一個物理地址緩存到兩個cache line中。當進程間經過共享內存方式通訊,或者一個進程經過mmap的方式內核與應用層共享內存,就會出現同同一塊物理內存,以多個虛擬地址訪問的狀況。就容易致使一塊物理內存緩存到兩個cache line中。
因爲共享內存是頁對其的,所以多個進程空間的共享內存,或者內核態用戶態的共享內存,其物理地址不一樣,但其頁偏移是相同的。
假如頁大小爲P = 2^p 字節,cache line爲 C = 2^c 字節,那麼共享內存的不一樣虛擬地址其低p位是一致的,假如地址0 -> c位用於block offset,c -> p 位用於set index,那麼就能夠避免cache alias的問題。
但若是set index 位數 > p -c ,那確定會出現cache alias的問題,由於同一塊物理內存,不一樣的虛擬地址,其set index不一樣。
針對於cache alias問題,目前的方案是由操做系統來保證,對於同一物理地址在不一樣進程空間的虛擬地址,要保證他們index相同,落在同一個set,就須要保證他們虛擬地址的差值是cache大小的整數倍。同時已經有些cpu廠商在開發監視模塊,試圖在硬件層面解決相似的同步問題。