內存屏障(Memory Barriers)

 參考wikipedia的定義:php

      Memory barrier, also known as membar or memory fence or fence instruction, is a type of barrier and a class of instruction which causes a central processing unit (CPU) or compiler to enforce an ordering constraint on memory operations issued before and after the barrier instruction.

內存屏障機制能夠用來解決不少問題。


1、解決多核Cache問題

當代計算機系統架構中有Cache的概念,而Cache會引入一些問題。內存屏障就是解決這些問題的一個方法。
強烈推薦看《Memory Barriers: a Hardware View for Software Hackers》




先來個簡單的例子,作多核CPU系統上,運行程序:

有全局變量a,b 它們都被初始化爲 0

Processor #0:css

  1. void foo(void)
  2. {
  3.    a = 1;
  4.    b = 1;
  5. }

Processor #1:架構

  1. void bar(void)
  2. {
  3.    while(b == 0) continue;
  4.    printk("%d\n",a);
  5. }


上面的例子中,指望輸出「1」,但結果並不老是這樣,有時會輸出"0"。
一個可能的序列是這樣:

a在CPU_1的cache裏
b在CPU_0的cache裏

1. CPU_0 執行 a = 1,
   爲了完成對a的寫操做,CPU_0 把value「1」放到buffer中,同時給CPU_1發送「read invalidate」,告訴別人a不能讀,我要改它
2. CPU_1 執行 while(b==0) continue;  
   爲了完成對b的讀操做,CPU_1 發出"read"給其餘CPU,告訴別人,別改b,我要讀它
3. CPU_0 執行 b = 1
   b在CPU_0的cache裏,直接更新b在cache裏的值

4. CPU_0 接收到了CPU_2的「read」
   CPU_0把「b」在Cache裏的值share給CPU_1

5. CPU_1 接收到「b」的share,把「b」放在本身的cache中

6. CPU_1 執行while(b==0) continue;
   再次去cache裏拿「b」的值,爲1, 從while循環中跳出

7. CPU_1 執行printk("%d\n",a);
   對a執行讀取操做,一看a在cache裏,爲0,拿出來,輸出「0」

8. CPU_1 收到 CPU_0 的「read invalidate」信息,把對「a」的cache控制權給CPU_0。
   此時太晚了,CPU_1已經使用了「a」的舊值

9. CPU_0接收到 「a」的cache控制權,更新其值爲「1」
    
使用內存屏障,能夠解決上述問題
Processor #2:ide

  1. = 22;
  2. smp_mb();
  3. = 1;

2、解決gcc編譯優化致使的問題

3、解決多核同步問題

4、API
5、不一樣架構上的實現優化

相關文章
相關標籤/搜索