volatile和內存屏障(dmb)

volatile

 

C語言中 volatile 關鍵字用於告訴編譯器,嚴禁將此處的彙編語句與其它的語句重組合優化。volatile只能保證編譯器不會做亂序執行優化.

 

      1. 不對*p操作生成亂序指令(通常如此,具體請看後面的解釋)

(比如條件判斷)

 

      2. 每次從*p取數據的時候,一定會進行一次訪存操作,哪怕前面不久才取過*p的值放在寄存器裏。

比如對於硬件寄存器的訪問,內存中的數據和cache中的數據可能不一致.

 

      3.不合並對*p的寫操作(也只是通常如此,解釋見後)

 

int *p;

volatile int *p1;

p = 1;  //這個被優化

p = 2;

p1 = 1;  //這個不會

p1 = 2;

 

但volatile無法保證 cpu運行時亂序執行.

 

內存屏障(memory barrier)

 

如果要想控制cpu運行是亂序執行優化則需有內存屏障.

 

 

#define isb() __asm__ __volatile__ ("isb" : : : "memory")

#define dsb() __asm__ __volatile__ ("dsb" : : : "memory")

#define dmb() __asm__ __volatile__ ("dmb" : : : "memory")

 

 

#define mb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)

#define rmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)

#define wmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)

 

#define set_mb(var, value) do { var = value; mb(); } while (0)

      1. set_mb(),mb(),barrier()函數追蹤到底,就是__asm__ __volatile__("":::"memory"),而這行代碼就是內存屏障。
      2. __asm__用於指示編譯器在此插入彙編語句
      3. __volatile__  相當於 C語言的volatile(見上面分析).
      4.  memory強制gcc編譯器假設RAM所有內存單元均被彙編指令修改,這樣cpu中的registers和cache中已緩存的內存單元中的數據              將作廢。cpu將不得不在需要的時候重新讀取內存中的數據。這就阻止了cpu又將registers,cache中的數據用於去優化指令,而避            免去訪問內存。
      5)"":::表示這是個空指令。barrier()不用在此插入一條串行化彙編指令。

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