天天看點

CPU緩存和記憶體屏障

CPU性能優化手段-緩存

為了提高程式運作的性能,現代CPU在很多方面對程式進行了優化。

例如:CPU高速緩存。盡可能地避免處理器通路主記憶體的時間開銷,處理器大多會利用緩存(cache)以提高性能。

多級緩存

L1 Cache(一級緩存)是CPU第一層高速緩存,分為資料緩存和指令緩存。一般伺服器CPU的L1緩存的容量通常在32-4096KB。

L2由于L1級高速緩存容量的限制,為了再次提高CPU的運算速度,在CPU外部放置-高速存儲器,即二級緩存。

L3現在的都是内置的。而它的實際作用即是,L3緩存的應用可以進一步降低記憶體延遲,同時提升大資料量計算時處理器的性能。具有較大L3緩存的處理器提供更有效的檔案系統緩存行為及較短消息和處理器隊列長度。一般是多核共享一個L3緩存!

CPU在讀取資料時,先在L1中尋找,再從L2尋找,再從L3尋找,然後是記憶體,再後是外存儲器。

緩存同步協定

多CPU讀取同樣的資料進行緩存,進行不同運算之後,最終寫入主記憶體以哪個CPU為準?

在這種高速緩存回寫的場景下,有一個緩存一緻性協定多數CPU廠商對它進行了實作。

MESI協定,它規定每條緩存有個狀态位,同時定義了下面四個狀态:

  • 修改态(Modified)-此cache行已被修改過(髒行),内容已不同于主存,為此cache專有;
  • 專有态(Exclusive)-此cache行内容同于主存,但不出現于其它cache中;
  • 共享态(Shared)-此cache行内容同于主存,但也出現于其它cache中;
  • 無效态(Invalid)-此cache行内容無效(空行)。

多處理器,單個CPU對緩存中資料進行了改動,需要通知給其它CPU。也就是意味着,CPU處理要控制自己的讀寫操作,還要監聽其他CPU發出的通知,進而保證最終一緻。

CPU性能優化手段-運作時指令重排

指令重排的場景:當CPU寫緩存時發現緩存區塊正被其他CPU占用,為了提高CPU處理性能,可能将後面的讀緩存指令優先執行。

并非随便重排,需要遵守as-if-serial語義

as-if-serial語義的意思指:不管怎麼重排序(編譯器和處理器為了提高并行度),(單線程)程式的執行結果不能被改變。編譯器,runtime和處理器都必須遵守as-if-serial語義。也就是說:編譯器和處理器不會對存在資料依賴關系的操作做重排序。

兩個問題

1、CPU高速緩存下有一個問題:

緩存中資料與主記憶體的資料并不是實時同步的,各CPU(或CPU核心)間緩存的資料也不是實時同步。

在同一個時間點,各CPU所看到同一記憶體位址的資料的值可能是不一緻的。

2、CPU執行指令重排序優化下有一個問題:

雖然遵守了as-if-serial語義,單僅在單CPU自己執行的情況下能保證結果正确。多核多線程中,指令邏輯無法分辨因果關聯,可能出現亂序執行,導緻程式運作結果錯誤。

記憶體屏障

處理器提供了兩個記憶體屏障指令(Memory Barrier)用于解決上述兩個問題:

寫記憶體屏障(Store Memory Barrier):在指令後插入Store Barrier,能讓寫入緩存中的最新資料更新寫入主記憶體,讓其他線程可見。強制寫入主記憶體,這種顯示調用,CPU就不會因為性能考慮而去對指令重排。

讀記憶體屏障(Load Memory Barrier):在指令前插入Load Barrier,可以讓高速緩存中的資料失效,強制從主記憶體加載資料。強制讀取主記憶體内容,讓CPU緩存與主記憶體保持一緻,避免了緩存導緻的一緻性問題。

繼續閱讀