1. 程式人生 > >指令的記憶體屏障 的 思考

指令的記憶體屏障 的 思考

隨便寫的,記在這裡,不一定對。

起因是我看的這篇中讀寫屏障的概念,恍惚覺得上編譯原理時好像聽到過這個詞
漫畫:什麼是volatile關鍵字?(整合版)

具體是這幾段:

什麼是記憶體屏障?
記憶體屏障(Memory Barrier)是一種CPU指令,維基百科給出瞭如下定義:
A memory barrier, also known as a membar, memory fence or fence instruction, is a type of barrier instruction that causes a CPU or compiler to enforce an ordering constraint on memory operations issued before and after the barrier instruction. This typically means that operations issued prior to the barrier are guaranteed to be performed before operations issued after the barrier.
翻譯結果如下:
記憶體屏障也稱為記憶體柵欄或柵欄指令,是一種屏障指令,它使CPU或編譯器對屏障指令之前和之後發出的記憶體操作執行一個排序約束。 這通常意味著在屏障之前釋出的操作被保證在屏障之後釋出的操作之前執行。

記憶體屏障共分為四種類型:

LoadLoad屏障
抽象場景:Load1; LoadLoad; Load2
Load1 和 Load2 代表兩條讀取指令。在Load2要讀取的資料被訪問前,保證Load1要讀取的資料被讀取完畢。

StoreStore屏障:
抽象場景:Store1; StoreStore; Store2
Store1 和 Store2代表兩條寫入指令。在Store2寫入執行前,保證Store1的寫入操作對其它處理器可見

LoadStore屏障:
抽象場景:Load1; LoadStore; Store2
在Store2被寫入前,保證Load1要讀取的資料被讀取完畢。

StoreLoad屏障
抽象場景:Store1; StoreLoad; Load2
在Load2讀取操作執行前,保證Store1的寫入對所有處理器可見。StoreLoad屏障的開銷是四種屏障中最大的。

volatile做了什麼?
在一個變數被volatile修飾後,JVM會為我們做兩件事:
1.在每個volatile寫操作前插入StoreStore屏障,在寫操作後插入StoreLoad屏障。
2.在每個volatile讀操作前插入LoadLoad屏障,在讀操作後插入LoadStore屏障。

有沒覺得 volatile 做的事情對稱性很強。
下面的例子,假設每一句都執行在不同的執行緒中(除了那個if塊)。
方便記憶吧。。

volatile int a;
a=1;
// store store 屏障,防止a=1 和 a=2 交換
a=2;
// store load 屏障, 防止print(a) 和 a=2  交換
print(a)
volatile int a;
auto result=do_job()
a=1;
// load load 屏障, 防止result 沒有賦值
if(a!=0){
// load store 屏障, 防止 a=0 和 a!=0 交換
print(result)
}
a=0