緩存的出現主要是爲了解決CPU運算速度與內存讀寫速度不匹配的矛盾,由於CPU運算速度要比內存讀寫速度快不少,這樣會使CPU花費很長時間等待數據到來或把數據寫入內存。緩存
當CPU要讀取一個數據時,首先從緩存中查找,若是找到就當即讀取並送給CPU處理;若是沒有找到,就用相對慢的速度從內存中讀取並送給CPU處理,同時把這個數據所在的數據塊調入緩存中,可使得之後對整塊數據的讀取都從緩存中進行,沒必要再調用內存。服務器
按照數據讀取順序和與CPU結合的緊密程度,CPU緩存能夠分爲一級緩存,二級緩存,部分高端CPU還具備三級緩存,每一級緩存中所儲存的所有數據都是下一級緩存的一部分,這三種緩存的技術難度和制形成本是相對遞減的,因此其容量也是相對遞增的。socket
性能提高:對於總體性能的做用,L1 cache最大,L2次之性能
一級緩存是相對於二級緩存來命名的,它是直接與CPU數據總線相連,傳輸速度接近於CPU處理速度。設計
一級緩存(Level 1 Cache)簡稱L1 Cache,位於CPU內核的旁邊,是與CPU結合最爲緊密的CPU緩存,一級緩存的技術難度和制形成本最高,提升容量所帶來的技術難度增長和成本增長很是大,所帶來的性能提高卻不明顯,性價比很低。blog
並且現有的一級緩存的命中率已經很高,因此一級緩存是全部緩存中容量最小的隊列
l1致力於更快的速度,所以採用哈佛結構是一種將程序指令存儲和數據存儲分開的存儲器結構。因此一級緩存能夠分爲一級數據緩存和一級指令緩存,可是AMD和inter採用不一樣的方式。數據和指令分離能夠作到減小衝突內存
而二級緩存和三級緩存都採用的是馮·諾依曼結構將程序指令存儲器和數據存儲器合併在一塊兒的存儲器結構。哈佛結構的微處理器一般具備較高的執行效率效率
而一級緩存小的緣由在於昂貴,並且作大了之後在一級緩存中查找數據也就慢了。硬件
二級緩存是CPU性能表現的關鍵之一,在CPU核心不變化的狀況下,增長二級緩存容量能使性能大幅度提升。
主要緣由在於二級緩存提升命中。
根據28定律,80%的的數據在均可以直接在一級緩存中找到,而剩下的20%的80%能夠再二級緩存中找到,所以就是說,96%的數據均可以在一二級緩存中找到。
其中一二級緩存,每一個核心都有一個,可是全部核心共享三級緩存
三級緩存是爲讀取二級緩存後未命中的數據設計的—種緩存,在擁有三級緩存的CPU中,只有約5%的數據須要從內存中調用,這進一步提升了CPU的效率。
三級緩存的做用是爲了進一步提升命中。
存在四級緩存等。
Intel 的CPU已經有增長L4緩存的版本了,不過這裏的L4主要用於解決核顯和CPU之間交換數據,稱爲eDRAM。原先的核顯沒有顯存,只能共享內存空間,限制了核顯性能和效率。如今在CPU和GPU之間增長了128MB的eDRAM,讓GPU與CPU作數據交換。
另外服務器cpu也有四級緩存
三級緩存的大小已經幾乎是核心體積的一半了,再加緩存cpu體積會增長。
cpu緩存和內存之間交換的數據,是長度固定的塊,稱爲緩存航.一般是2^n,通常16~256字節不等.
大量緩存是經過硬件哈希表來實現的.這些哈希表有固定長度的哈系桶.
每一個桶可以存儲一個緩存行大小的數據.而後幾個桶組成一路.也就是哈希值定位到的位置.
通常哈希都比較簡單,單純的使用4位來表示,所以也就是說有16路.每路多個桶.
緩存一致性協議管理緩存行的狀態.防止數據不一致或是丟失數據.
協議十分複雜,每個緩存行行有十幾種可選的狀態.可是基本的有下面四中:
exclusive:獨佔,而且沒有修改.也就是說某個cpu核心獨佔了該緩存,在其餘的核心中都沒有緩存該緩存行.而且該核心尚未修改該緩存行的數據,所以他能夠丟棄該緩存,或是轉移給其餘核心
modified:獨佔,而且修改了該緩存,該核心擁有該緩存行的最新數據.所以必需要將其寫會內存或是移交給其餘核心
shared:非獨佔,多個核心可同時保持該緩存.可是不能修改,也不須要轉交給別的核心
invalid:無效,也就是說該緩存行爲空,以前的緩存行從該核心中移除了.
當一個核心須要讀數據的時候,須要想起他cpu廣播,那麼擁有該緩存的,核心須要響應這個讀消息.modified狀態的緩存行的核心,必需要相應這個消息.而後將緩存行移交給核心,緩存行狀態設置爲shared
寫,須要向其餘核心發送使無效消息
當一個核心要覆蓋某個緩存行中的數據是,也就是說要賦值,而不是簡單的遞增.
那麼該核心收到該緩存之後就要將該緩存行覆蓋,也就是說他並不須要緩存行中的數據.
可是爲了等待該緩存行的到來.須要時間.
所以爲了加速這種操做.cpu在緩存之間有加了一個存儲緩衝.
也就是這些須要直接賦值(能夠理解爲直接覆蓋)的緩存行先存儲到存儲緩衝中.當緩存行到了之後再覆蓋回去.
可是,這種加速操做,是存在問題的:
在存儲緩衝中的緩存行,必須須要等待緩存中的緩存行到來之後才能將其寫到緩存中的緩存行.
而且,若是緩存行沒有讀到緩衝以前的這段時間,cpu會繼續其餘的操做.例如修改該核心獨佔的存儲緩衝.
例如,cpu1,要覆蓋a,可是緩存行a,不在cpu1.同時cpu1還要修改b,b在本身的緩衝中.
cpu2,須要判斷b的值,而後對a進行操做.而且持有緩存行a
因此,cpu1由於要覆蓋a,所以覆蓋後的a存儲在存儲緩衝中,而且向其餘核心,發送使讀無效消息.(使讀無效消息,延時到達cpu2,也就是說cpu之間的通訊不是隊列形式的,和socket有的一拼)而後繼續去修改b.而且在緩存行a到來以前,修改完b了.
而後cpu2發送讀b的消息.cpu1收到之後,發送本身的緩存行b.而後cpu2收到緩存行b之後,判斷b的值,能夠進行下面的操做了.可是此時緩存行a的使讀無效消息尚未到,所以cpu2此時使用的是a的舊數據.
也就是說數據不一致的行爲的根源在於,cpu將要覆寫的數據存儲在存儲緩衝中,繼續執行別的指令.同時使讀無效消息到達別的cpu以前,別的cpu,由於以前阻塞,可是在使讀無效消息到達以前,阻塞解除.使用了該數據.
其實,理解3個cpu更好,由於那個使讀無效消息到達的太晚了.
而內存屏障就是爲了解決這個問題的.在於,當執行一條語句之後,若是該語句的消息必須實時更新.
那麼使用內存屏障,會將該語句後面的修改語句都存儲到存儲緩衝裏,而後當須要修改的緩存行到達緩衝中,纔會將存儲緩衝裏的數據依次寫到緩存行裏.
這樣就避免了緩存不一致的行爲.
也就是說內存屏障的意義在於,在內存屏障語句調用以前,必須先講存儲緩衝中的數據所有刷新回緩存行,後面語句修改的數據纔可以再次修改緩衝行,不然,就要放入存儲緩衝中.
現代處理器採用指令並行技術-流水線,在不存在數據依賴性的前提下,處理器能夠改變語句對應的機器指令的執行順序來提升處理器執行速度.
這個過程是不會引發數據不一致的.由於操做若是存在數據依賴的狀況,那麼使用同一數據的指令,必定是按順序執行的.並不會亂序.
只有使用不一樣數據的執行之間纔會亂序.