如果有人問你:啥叫CPU Cache?

  咋回答?

  讓我們先來看看Cache與CPU的奇妙糾葛

  Cache一詞源自法語,其原意是「藏匿處,隱秘的地方」。Cache被應用於計算機科學之後,專指CPU與主內存之間的高速緩衝存儲器。 Cache的出現是為了緩解CPU的存儲需求與主內存的存取性能之間越來越大的差距。

  現代CPU的Cache都是集成在片內的,越靠近CPU流水線的Cache由於需要極其快速的存取速度,只能保持越小的容量,並且單位容量的成本越高。

  因此,為了進一步緩解需求與性能之間的差距,並應對不斷增大的主內存,最新的CPU都採用三級Cache結構。

  1

  靠近CPU流水線的L1 Cache速度最快、容量最小

  2

  L2 Cache速度與容量都居中

  3

  靠近主內存的L3 Cache則是容量最大,但速度相對最慢(仍然比主內存快很多)。

  4

  此外,為了能使指令與數據都得到最快的響應,L1 Cache中的指令部分與數據部分是相互獨立的, 分別為指令L1-I Cache與數據L1-D Cache;

  而L2 Cache與L3 Cache則是將指令與數據混合存儲的。

  CPU存儲結構示意

  看到這裡 你會覺得

  嗯 CPU Cache大約么就是這麼回事情嘛

  but...如果再問你

  CPU Cache的工作原理又是啥呢?

  局部性原理

  一般的計算機程序對存儲器的訪問行為,存在很大的局部性,主要分為兩個方面:

  時間局部性與空間局部性。

  → 時間局部性,即程序會在一個比較短的時間窗口內頻繁訪問同一個內存地址。

  → 空間局部性,即程序會傾向於訪問一組數據或者一個數據相鄰的數據。

  Cache正是利用了程序訪存的這兩個局部性特點,將程序最常使用的指令與數據放在離CPU流水線最近的地方,以便在需要時最快地獲取這部分指令與數據。

  映射關係

  Cache中存儲的內容是主內存的一個子集,越是常用的指令與數據,越可能出現在離CPU流水線近的Cache中。

  主內存中的數據按照一定的映射關係,以塊(也稱為行)為單位存入Cache中。這其中的映射關係決定了Cache塊放置的位置。

  Cache與主內存、Cache與Cache之間的映射關係,是影響Cache性能的重要因素之一。

  映射關係主要分為三種:

  全相聯映射、直接映射與組相聯映射。

  → 全相聯映射

  主存中的任一塊可以被放置到Cache中的任意一個位置。其特點是空間利用率高,衝突概率最低,實現最複雜。

  → 直接映射

  主存中的每一塊只能被放置到Cache中的唯一的一個位置。其特點是空間利用率低,衝突概率最高,實現最簡單。

  → 組相聯映射

  主存中的每一塊可以被放置到Cache中的唯一的一個組中的任何一個位置。組相聯映射是直接映射和全相聯映射的一種折中。

  → n路組相聯

  如果組內有n個塊,則稱該緩存位置為n路組相聯。相聯度越高,Cache空間的利用率就越高,塊衝突概率就越低,缺失率也就越低。

  查找演算法

  針對常用的組相聯映射方式,Cache塊的查找是通過查找目錄來實現的。

  首先將物理地址從低位到高位分為三個部分:

  塊偏移、索引以及標誌(tag)。

  塊偏移欄位從塊中選擇期望數據,

  其位數由塊大小決定,

  常用的塊大小為64B,對應6bit。

  索引欄位選擇組,

  組的數量由具體設計決定,

  組數確定了索引欄位的位數也就確定了。

  組選定後,通過對比組中

  所有路的標誌欄位與目標物理地址的標誌欄位

  是否一致來判斷是否命中,

  若命中即查找到了所需訪問的指令或數據。

  查找演算法對應的物理地址劃分

  查找Cache塊流程示意圖

  替換策略

  當調入一個新塊,而Cache被佔滿時,應該替換哪一塊?

  對於直接映射,只有一個塊別無選擇;對於全相聯或組相聯,則有多個塊可以進行選擇。

  主要的替換方法有以下幾種:

  隨機、FIFO以及LRU。

  隨機

  顧名思義就是隨機選擇一個塊進行替換。

  FIFO

  即先進先出,將最早進入Cache的塊替換出去。

  LRU

  全稱為Least Recently Used,即最近最少使用替換法,也就是將最近最少使用的塊替換出去。

  LRU是主流的替換演算法,為了進一步降低由替換引起的缺失率,在LRU基礎上又發展出很多更高級的替換演算法,如NRU、MLP以及RRIP等。

  寫策略

  寫操作必須是確認在命中後才可進行。

  寫訪問有可能會導致Cache和主存內容不一致。

  兩種寫策略:

  → 直寫(write-through):

  執行寫操作時,不僅寫入Cache,

  而且也寫入下一級存儲器。

  → 回寫(write-back):

  執行寫操作時,只寫入Cache,

  僅當Cache中相應的塊被替換時,才寫回主存。

  兩種寫策略的比較:

  → 直寫(write-through):

  簡單易實現,所有層次都具有相同的數據,

  便於維護一致性,但是寫的次數較多,

  對帶寬需求比較大。

  在進行寫操作的過程中CPU必須等待。

  → 回寫(write-back):

  在往主存寫時,將多次合為一次。

  降低了寫主存的次數,降低了帶寬,節省功耗,

  但需要額外添加一個修改位。

  寫入分配的比較:

  → 寫入分配(Allocate):

  寫miss時,先把所寫單元所在的塊調入Cache,

  再進行寫操作。能夠將多次寫合為一次,且寫與讀相似。

  → 無寫入分配( No-allocate ):

  寫miss時,直接寫入下一級存儲器而不調入Cache。

  節省了Cache的空間。

  塊的粒度

  如果塊太大,那麼塊的數目會變少,寫操作和讀操作會有許多無用的數據,佔據帶寬較大,功耗大。

  相反如果塊太小,會導致未完全利用空間局域性,並使用更多的Tag,邏輯消耗大。

  塊大小與命中率的關係

  好啦 關於CPU Cache的碎碎念就到這裡

  相信以你的聰(xia)明(la)才(su)智(du)

  一定分分鐘看完啦

  要是5分鐘沒看完....

  可至專業IC教育平台「E課網」官網漲知識


推薦閱讀:
相关文章