volatile是怎麼保障內存可見性以及防止指令重排序的?

1、內存可見性

內存可見性的表面意思是一個CPU核心對數據的修改,對其他CPU核心立即可見,但其實這麼說挺不好理解的,我們反過來理解,就是某一個CPU核心對數據的修改會導致其他CPU核心上的數據失效,造成的結果就是,其他CPU核心再去使用這個數據的時候,就必須要去主存重新獲取。

實現的原理是基於CPU的MESI協議,其中E表示獨佔Exclusive,S表示Shared,M表示Modify,I表示Invalid,如果一個核心修改了數據,那麼這個核心的數據狀態就會更新成M,同時其他核心上的數據狀態更新成I,這個是通過CPU多核之間的嗅探機制實現的。

 

2、指令重排序

這個涉及到內存屏障(Memory Barrier),它是讓一個CPU處理單元中的內存狀態對其它處理單元可見的一項技術。

內存屏障有兩個能力:

a、就像一套柵欄分割前後的代碼,阻止柵欄前後的沒有數據依賴性的代碼進行指令重排序,保證程序在一定程度上的有序性。
b、強制把寫緩衝區/高速緩存中的髒數據等寫回主內存,讓緩存中相應的數據失效,保證數據的可見性。

內存屏障有三種類型和一種僞類型:

a、lfence:即讀屏障(Load Barrier),在讀指令前插入讀屏障,可以讓高速緩存中的數據失效,重新從主內存加載數據,以保證讀取的是最新的數據。
b、sfence:即寫屏障(Store Barrier),在寫指令之後插入寫屏障,能讓寫入緩存的最新數據寫回到主內存,以保證寫入的數據立刻對其他線程可見。
c、mfence,即全能屏障,具備ifence和sfence的能力。
d、Lock前綴:Lock不是一種內存屏障,但是它能完成類似全能型內存屏障的功能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章