CPU性能優(yōu)化手段 - 緩存
為了提高程序的運行性能, 現(xiàn)代CPU在很多方面對程序進行了優(yōu)化
例如: CPU高速緩存, 盡可能的避免處理器訪問主內(nèi)存的時間開銷, 處理器大多會利用緩存以提高性能
多級緩存
L1 Cache (一級緩存)是CPU第一層高速緩存, 分為數(shù)據(jù)緩存和指令緩存, 一般服務(wù)器CPU的L1緩存的容量通常在32-4096kb
L2 Cache (二級緩存) 由于L1高速緩存的容量限制, 為了再次提高CPU的運算速度, 在CPU外部放置一高速緩存存儲器, 即二級緩存
L3 Cache(三級緩存)現(xiàn)在都是內(nèi)置的, 而它的實際作用既是, L3緩存的應(yīng)用可以進一步降低內(nèi)存延遲, 同時提升大數(shù)據(jù)量計算時處理器的性能. 具有較大L3緩存的處理器更有效的文件系統(tǒng)緩存行為及較短消息和處理器隊列長度. 一般是多核共享一個L3緩存
CPU在讀取數(shù)據(jù)時, 先在L1中尋找, 再從L2中尋找, 再從L3中尋找, 然后是內(nèi)存, 最后是外存儲器
緩存同步協(xié)議
多CPU讀取同樣的數(shù)據(jù)進行緩存, 進行不同運算之后, 最終寫入主內(nèi)存以那個CPU為準(zhǔn)? 在這種高速緩存回寫的場景下, 有一個緩存一致性協(xié)議, 多數(shù)CPU廠商對它進行了實現(xiàn).
即MESI協(xié)議, 它規(guī)定每條緩存有個狀態(tài)位, 同時定義了下面四種狀態(tài):
- 修改態(tài)(Modified) 此cache行已被修改過(臟行), 內(nèi)容已不同于主內(nèi)存, 為此cache專有
- 專有態(tài)(Exclusive) 此cache行同于主存, 但它不出現(xiàn)于其他cache中
- 共享態(tài)(Shared) 此cache行同于主存, 但也出現(xiàn)于其他cache中
- 無效態(tài)(Invalid) 此cache行無效(空行)
多處理時, 單個CPU對緩存中的數(shù)據(jù)進行了改動, 需要通知給其他CPU, 也就意味著, CPU處理要控制自己的讀寫操作, 還要監(jiān)聽其他CPU發(fā)出的通知, 從而保證最終一致
CPU性能優(yōu)化手段 - 運行時指令重排
指令重排的場景: 當(dāng)CPU寫緩存時發(fā)現(xiàn)緩存區(qū)塊正被其它CPU占用, 為了提高CPU處理性能, 可能將后面的讀緩存命令優(yōu)先執(zhí)行.
當(dāng)然也并非隨便重排, 需要遵循as-if-serial語義
as-if-serial語義的意思指: 不管怎么重排序, 程序的執(zhí)行結(jié)果不能被改變
編譯器, runtime和處理器都必須遵守as-if-serial語義, 也就是說, 編譯器和處理器不會對存在數(shù)據(jù)依賴關(guān)系的操作做重排序
兩個問題
CPU高速緩存下有一個問題:
緩存中的數(shù)據(jù)與主內(nèi)存的數(shù)據(jù)并不是實時同步的, 各CPU間緩存的數(shù)據(jù)也不是實時同步. 在同一時間點, 各CPU所看到的同一內(nèi)存地址的數(shù)據(jù)的值可能是不一致的.CPU執(zhí)行指令重排序優(yōu)化的一個問題:
雖然遵守了as-if-serial語義, 但僅在單CPU自己執(zhí)行的情況下能保證結(jié)果正確. 多核多線程中, 指令邏輯無法分辨因果關(guān)聯(lián), 可能出現(xiàn)亂序執(zhí)行, 導(dǎo)致程序運行結(jié)果錯誤
解決方法 - 內(nèi)存屏障
處理器提供了兩個內(nèi)存屏障指令(Memory Barrier)用于解決上述兩個問題:
寫內(nèi)存屏障(Store Memory Barrier): 在指令后插入Store Barrier, 能讓寫入緩存中的最新數(shù)據(jù)更新寫入主內(nèi)存, 讓其他線程可見
強制寫入主內(nèi)存, 這種顯示調(diào)用, CPU就不會因為性能考慮而進行指令重排
讀內(nèi)存屏障(Load Memory Barrier): 在指令前插入Load Barrier, 可以讓高速緩存中的數(shù)據(jù)失效, 強制從新從主內(nèi)存讀取數(shù)據(jù)
強制讀取主內(nèi)存內(nèi)容, 讓CPU緩存和主內(nèi)存保持一致, 避免了緩存導(dǎo)致的一致性問題