初步认识Volatile-MESI优化带来的可见性问题
MESI協議雖然可以實現緩存的一致性,但是也會存在一些問題。?
就是各個CPU緩存行的狀態是通過消息傳遞來進行的。如果CPU0要對一個在緩存中共享的變量進行寫入,首先需要發送一個失效的消息給到其他緩存了該數據的CPU。并且要等到他們的確認回執。CPU0在這段時間內都會處于阻塞狀態。為了避免阻塞帶來的資源浪費。在cpu中引入
了Store?Bufferes。?
CPU0只需要在寫入共享數據時,直接把數據寫入到store?bufferes中,同時發送invalidate消息,然后繼續去處理其他指令。
當收到其他所有CPU發送了invalidate acknowledge消息時,再將store?bufferes中的數據數據存儲至cache line中。最后再從緩存行同步到主內存。
但是這種優化存在兩個問題
1. 數據什么時候提交是不確定的,因為需要等待其他cpu給回復才會進行數據同步。這里其實是一個異步操作
2. 引入了storebufferes后,處理器會先嘗試從storebuffer中讀取值,如果storebuffer中有數據,則直接從storebuffer中讀取,否則就再從緩存行中讀取
我們來看一個例子
exeToCPU0和exeToCPU1分別在兩個獨立的CPU上執行。假如CPU0的緩存行中緩存了isFinish這個共享變量,并且狀態為(E)、而Value可能是(S)狀態。
那么這個時候,CPU0在執行的時候,會先把value=10的指令寫入到storebuffer中。并且通知給其他緩存了該value變量的CPU。在等待其他CPU通知結果的時候,CPU0會繼續執行isFinish=true這個指令。?
而因為當前CPU0緩存了isFinish并且是Exclusive狀態,所以可以直接修改isFinish=true。這個時候CPU1發起read操作去讀取isFinish的值可能為true,但是value的值不等于10。
這種情況我們可以認為是CPU的亂序執行,也可以認為是一種重排序,而這種重排序會帶來可見性的問題
這下硬件工程師也抓狂了,我們也能理解,從硬件層面很難去知道軟件層面上的這種前后依賴關系,所以沒有辦法通過某種手段自動去解決。
所以硬件工程師就說:既然怎么優化都不符合你的要求,要不你來寫吧。
所以在CPU層面提供了?memory barrier(內存屏障)的指令,從硬件層面來看這個?memroy barrier就是CPU flush?store bufferes中的指令。軟件層面可以決定在適當的地方來插入內存屏障。
?
總結
以上是生活随笔為你收集整理的初步认识Volatile-MESI优化带来的可见性问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 初步认识Volatile-总结可见性的本
- 下一篇: 初步认识Volatile-CPU层面的内