ARM有幾條memory barrier 的指令?分別有什麽區別?
從ARMv7指令集開始,ARM提供3條內存屏障指令。
(1)數據存儲屏障( Data Memory Barrier,DMB)
數據存儲器隔離。DMB指令保證:僅當所有在它前面的存儲器訪問操作都執行完畢後,才提交( commit)在它後面的存取訪問操作指令。當位於此指令前的所有內存訪問均完成時,DMB指令才會完成
(2)數據同步屏障( Data synchronization Barrier,DSB)
數據同步隔離。比DMB要嚴格一些,僅當所有在它前面的存儲訪問操作指令都執行完畢後,才會執行在它後面的指令,即任何指令都要等待DSB前面的存儲訪問完成。位於此指令前的所有緩存,如分支預測和TLB( Translation Look- aside Buffer)維護操作全部完成
(3)指令同步屏障( Instruction synchronization Barrier,ISB)
指令同步隔離。它最嚴格,沖洗流水線( Flush Pipeline)和預取buer( pretcLbuffers後,才會從 cache或者內存中預取ISB指令之後的指令。ISB通常用來保證上下文切換的效果,例如更改ASID( Address Space Identifier)、TLB維護操作和C15寄存器的修改等。
內存屏障指令的使用例子如下。
例1:假設有兩個CPU核A和B,同時訪問 AddrE和Addr2地址。
Core A:
STR R0, [Addr1]
LDR R1, [Addr2]Core B:
STR R2, [Addr2]
LDR R3, [Addr1]
對於上面代碼片段,沒有任何的同步措施。對於 Core A、寄存器R1、 Core B和寄存器R3,可能得到如下4種不同的結果。
- A得到舊的值,B也得到舊的值。
- A得到舊的值,B得到新的值。
- A得到新的值,B得到舊的值。
- A得到新的值,B得到新的值。
例2:假設 Core a寫入新數據到Msg地址, Core B需要判斷flag標誌後才讀入新數據。
Core A
STR R0,[Msg] @寫新數據到Msg地址
STR R1,[F1ag] @F1ag標誌新數據可以讀
Core B
Poll loop:
LDR R1, [Flag]CMP R1, #0 @判斷flag有沒有置位
BEQ Poll loop
LDRR0,[Msg] @讀取新數據
在STR 存儲指令之後插入DSB指令,強制讓寫命令完成,然後執行讀取flag的判斷循環;
ARM有幾條memory barrier 的指令?分別有什麽區別?