CPU的緩存L1、L2、L3與緩存行填充


https://juejin.im/post/6844904071166427143

 

L1,L2,L3 指的都是CPU的緩存,他們比內存快,但是很昂貴,所以用作緩存,CPU查找數據的時候首先在L1,然后看L2,如果還沒有,就到內存查找一些服務器還有L3 Cache,目的也是提高速度。

高速緩沖存儲器Cache是位於CPU與內存之間的臨時存儲器,它的容量比內存小但交換速度快。在Cache中的數據是內存中的一小部分,但這一小部分是短時間內CPU即將訪問的,當CPU調用大量數據時,就可避開內存直接從Cache中調用,從而加快讀取速度。由此可見,在CPU中加入Cache是一種高效的解決方案,這樣整個內存儲器(Cache+內存)就變成了既有Cache的高速度,又有內存的大容量的存儲系統了。CacheCPU的性能影響很大,主要是因為CPU的數據交換順序和CPUCache間的帶寬引起的。



高速緩存的工作原理

1. 讀取順序

CPU要讀取一個數據時,首先從Cache中查找,如果找到就立即讀取並送給CPU處理;如果沒有找到,就用相對慢的速度從內存中讀取並送給CPU處理,同時把這個數據所在的數據塊調入Cache中,可以使得以后對整塊數據的讀取都從Cache中進行,不必再調用內存。

正是這樣的讀取機制使CPU讀取Cache的命中率非常高(大多數CPU可達90%左右),也就是說CPU下一次要讀取的數據90%都在Cache中,只有大約10%需要從內存讀取。這大大節省了CPU直接讀取內存的時間,也使CPU讀取數據時基本無需等待。總的來說,CPU讀取數據的順序是先Cache后內存。

2. 緩存分類

前面是把Cache作為一個整體來考慮的,現在要分類分析了。IntelPentium開始將Cache分開,通常分為一級高速緩存L1二級高速緩存L2

在以往的觀念中,L1 Cache是集成在CPU中的,被稱為片內Cache。在L1中還分數據Cache(I-Cache)和指令Cache(D-Cache)。它們分別用來存放數據和執行這些數據的指令,而且兩個Cache可以同時被CPU訪問,減少了爭用Cache所造成的沖突,提高了處理器效能。

 

在P4處理器中使用了一種先進的一級指令Cache——動態跟蹤緩存。它直接和執行單元及動態跟蹤引擎相連,通過動態跟蹤引擎可以很快地找到所執行的指令,並且將指令的順序存儲在追蹤緩存里,這樣就減少了主執行循環的解碼周期,提高了處理器的運算效率。

以前的L2 Cache沒集成在CPU中,而在主板上或與CPU集成在同一塊電路板上,因此也被稱為片外Cache。但從PⅢ開始,由於工藝的提高L2 Cache被集成在CPU內核中,以相同於主頻的速度工作,結束了L2 Cache與CPU大差距分頻的歷史,使L2 CacheL1 Cache在性能上平等,得到更高的傳輸速度。L2Cache只存儲數據,因此不分數據Cache和指令Cache。在CPU核心不變化的情況下,增加L2 Cache的容量能使性能提升,同一核心的CPU高低端之分往往也是在L2 Cache上做手腳,可見L2 Cache的重要性。現在CPUL1 CacheL2 Cache惟一區別在於讀取順序。

3. 讀取命中率

CPUCache中找到有用的數據被稱為命中,當Cache中沒有CPU所需的數據時(這時稱為未命中),CPU才訪問內存。從理論上講,在一顆擁有2級CacheCPU中,讀取L1 Cache的命中率為80%。也就是說CPUL1 Cache中找到的有用數據占數據總量的80%,剩下的20%從L2 Cache讀取。由於不能准確預測將要執行的數據,讀取L2的命中率也在80%左右(從L2讀到有用的數據占總數據的16%)。那么還有的數據就不得不從內存調用,但這已經是一個相當小的比例了。在一些高端領域的CPU(像IntelItanium)中,我們常聽到L3 Cache,它是為讀取L2 Cache后未命中的數據設計的—種Cache,在擁有L3 CacheCPU中,只有約5%的數據需要從內存中調用,這進一步提高了CPU的效率。

為了保證CPU訪問時有較高的命中率,Cache中的內容應該按一定的算法替換。一種較常用的算法是“最近最少使用算法”(LRU算法),它是將最近一段時間內最少被訪問過的行淘汰出局。因此需要為每行設置一個計數器,LRU算法是把命中行的計數器清零,其他各行計數器加1。當需要替換時淘汰行計數器計數值最大的數據行出局。這是一種高效、科學的算法,其計數器清零過程可以把一些頻繁調用后再不需要的數據淘汰出Cache,提高Cache的利用率。

緩存行填充

CPU訪問內存時,並不是逐個字節訪問,而是以字長為單位訪問。比如32位的CPU,字長為4字節,那么CPU訪問內存的單位也是4字節。

這么設計的目的,是減少CPU訪問內存的次數,加大CPU訪問內存的吞吐量。比如同樣讀取8個字節的數據,一次讀取4個字節那么只需要讀取2次。

我們來看看,編寫程序時,變量在內存中是否按內存對齊的差異。有2個變量word1、word2

圖如下:


我們假設CPU4字節為單位讀取內存。如果變量在內存中的布局按4字節對齊,那么讀取a變量只需要讀取一次內存,即word1;讀取b變量也只需要讀取一次內存,即word2

而如果變量不做內存對齊,那么讀取a變量也只需要讀取一次內存,即word1;但是讀取b變量時,由於b變量跨越了2個word,所以需要讀取兩次內存,分別讀取word1word2的值,然后將word1偏移取后3個字節,word2偏移取前1個字節,最后將它們做或操作,拼接得到b變量的值。

顯然,內存對齊在某些情況下可以減少讀取內存的次數以及一些運算,性能更高。

另外,由於內存對齊保證了讀取b變量是單次操作,在多核環境下,原子性更容易保證。

但是內存對齊提升性能的同時,也需要付出相應的代價。由於變量與變量之間增加了填充,並沒有存儲真實有效的數據,所以占用的內存會更大。這也是一個典型的空間換時間的應用場景。

參考文章


作者:簡棧文化
鏈接:https://juejin.im/post/6844904071166427143
來源:掘金
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM