首先,必須介紹超級好站 : http://preshing.com/
還有這個:http://bartoszmilewski.com/2008/12/01/c-atomics-and-memory-ordering/
memory_order_acquire : 保證其下面的 load 一定不會在其前面執行 !!
memory_order_release: 保證其上面的 store 不會拖到其後面才執行 !!
memory_order_acq_rel: 保證上面兩個
memory_order_consume: 相關變數間的保證順序 , 例如指標 , weak memory model 的 cpu ,
執行指令不像 strong memory model like intel,AMD 那麼嚴格 , 連指標內容更改後再 derefrence
都可能改變執行順序
memory_order_relaxed : do whatever order it like to do !!
Intel cpu 是我最常用的硬體 , 它是 TSO 架構 , Total Store Ordering , 其保證 :
1. store / store ordering
2. load / load ordering
3. load / store ordering
唯一不保證 : store/load ordering
store/load 最有名的例子 : (x=0;y=0; initially)
Thread1 : x=1 ; r1= y ;
Thread2 : y =1 ; r2 =x ;
假如 Thread1 先 load y 才執行 store x =1 ; 而且 Thread2 先執行 load x 才執行 store y = 1 ;
那麼這兩個 threads 執行完後 , 有可能出現 r1=0 ; r2 = 0 ;
Intel 都可能出現這個結果, 更別說其他 weak memory model 的 cpu ,
Intel cpu 每個 core 都有一個 store Buffer , 當執行 x = 1 ; 時 ,如果 x 變數所在的 cache line 不在它的 cache,
此時會將 x = 1 寫到 store buffer , 再往下執行,...First In First Out 的 store buffer 就是它 store/store gurantee 的原因,
此時, 如果 y變數 cache line 在它的 cache , 此時 load y 再 store to r1 , 寫入 store buffer , 這時 ,
單這個 core 看到的,就是 x=1;r1=0; ....所以,你應該可以看出來, r1=0 and r2=0 是怎樣出現的 !!
假設 Thread1 執行以下程式 :
x=1;
y=1;
z=1;
Thread2 :
if(z==1)
{
x==1 ?
y==1 ?
}
如果是 intel , AMD, x ==1 and y==1 一定成立, 因為 store/store , load/load ordering 的關係 ,
其他 weak memory model cpu 不一定 , 因為 z=1 不一定比 x=1 後執行,
load 順序也可以跳著來 !!!!!
c++11 用 atomic 以及 ordering 來處理此狀況,如以下 :
Thread1 :
x.store(1,memory_order_relaxed) ;
y.store(1,memory_order_relaxed) ;
z.store(1,memory_order_release) ;
Thread2 :
if(z.load(memory_order_acquire)==1)
{
x.load(memory_order_relaxed)==1 ?
y.load(memory_order_relaxed)==1 ?
}
留言列表