多線程 - 內存屏障和cpu緩存


CPU性能優化 - 緩存

為了提高程序運行的性能,現代CPU在很多方面會對程序進行優化。CPU的處理速度是很快的,內存的速度次之,硬盤速度最慢。在cpu處理內存數據中,內存運行速度太慢,就會拖累cpu的速度。為了解決這樣的問題,cpu設計了多級緩存策略。

CPU分為三級緩存: 每個CPU都有L1,L2 但是L3是多核公用的。

  • L1 Cache (一級緩存)是CPU第一層告訴緩存,分為數據緩存和指令緩存。一般服務器的CPU的L1緩存的容量通常在32-4096K
  • L2 Cache (二級緩存)由於L1高速緩存的容量限制,為了再次提高CPU的運算速度,在CPU外部放置一告訴存儲器,即二級緩存。
  • L3 Cache (三級緩存) 都是內置的,它的作用是進一步降低內存延遲,同事提升大數據量計算時處理器的性能。具有較大L3緩存的處理器,能提供更有效的文件系統緩存行為及較短的消息和隊列長度。一般多核共享一個L3緩存。

CPU查找數據的順序為: CPU -> L1 -> L2 -> L3 -> 內存 -> 硬盤

緩存同步協議

因為每個CPU都有自己的緩存,容易導致一種情況就是 如果多個CPU的緩存(多CPU讀取同樣的數據進行緩存,進行不同運算后,寫入內存中)中都有同樣一份數據,那這個數據要如何處理呢?已誰的為准? 這個時候就需要一個緩存同步協議了!
MESI協議 規定每條緩存都有一個狀態位,同時定義了一下四種狀態:

  • 修改態 (Modified) 此緩存被修改過,內容與住內存不同,為此緩存專有
  • 專有態 (Exclusive) 此緩存與主內存一致,但是其他CPU中沒有
  • 共享態 (Shared) 此緩存與住內存一致,但也出現在其他緩存中。
  • 無效態 (Invalid) 此緩存無效,需要從主內存中重新讀取。

多處理器,單個CPU對緩存修改,需要通知其他CPU. 也就意味着,CPU需要控制自己的讀寫,還需要監聽其他CPU發出的通知,從而保持最終一致性。

CPU性能優化 - 運行時指令重排序

例如如下代碼是:

指令重排:當CPU 寫緩存 時發現緩存區被其他CPU占用,為了提高CPU處理性能,可能將后面的讀緩存命令優先執行
指令重排序,遵循 as-if-serial語義。即指令重排序前后,程序執行的結果不能變化。對於數據有依賴的部分,不會進行重排序。

問題

1、CPU高速緩存的問題:
緩存中的數據與主內存的數據不是實時同步的,各個CPU間緩存的數據也不是實時同步的,在同一時間點,各個CPU所看到的的同一內存地址的數據可能是不一致的

2、CPU指令重排優化問題:
雖然遵循 as-if-serial語義,但是它是僅在單個CPU自己執行的情況下保證結果正確,多核多線程,指令邏輯無法分辨因果關聯,可能出現亂序執行,導致程序結果出現錯誤。

內存屏障解決以上問題

寫內存屏障(Store Memory Barrier):在指令后插入Store Barrier,能讓寫入緩存中最新數據更新寫入主內存中,讓其他線程可見。 強制寫入主內存,這種顯示調用,不會讓CPU去進行指令重排序
讀內存屏障(Load Memory Barrier):在指令后插入Load Barrier,可以讓高速緩存中的數據失效,強制重新從住內存中加載數據。 也是不會讓CPU去進行指令重排。


免責聲明!

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



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