http://preshing.com/20131125/acquire-and-release-fences-dont-work-the-way-youd-expect/

 

非常不錯的說明 ,  關於 release/acquire  operation 跟 release/acquire fence 的不同 !!!

xxx.store(yyy,std::memory_order_release)  這就是  release operation !

std::atomic_thread_fence(std::memory_order_release)  這就是 release fence !

 

所謂 release 語法 , 就是防止比它更早的 memory operations 拖到比它晚執行 ,

所謂 acquire 語法 , 就是防止比它更晚的 memory operations 提早到比它早執行 ,

 

那麼 ,  release operation 跟 release fence 差別在哪 ?  上述為例, release operation 是 防止

xxx.store 以上的 memory operation 不能在它(only)之後被執行 ,  但是 , 不能防止被 xxx 之後的 store 搶先執行 !!

release fence 則禁止 其以上的指令 拖到比它更晚的任何指令執行 !!!!

 

也就是說 :

aaa.store(1,memory_order_relax) ;

bbb.store(2,memory_order_relax) ;

ccc.store(3,memory_order_relax) ;

ddd.store(4,memory_order_release) ;

eee.store(4,memory_order_relax) ;

保證 ddd 執行時, 已經執行過 aaa,bbb,ccc , 但是沒有保證 eee 執行時 , aaa,bbb,ccc已經執行了 !!

 

之所以這麼複雜是因為 cpu 可以自由執行程式碼 ,  cpu 有 strong memory 以及 weak memory model ,

像是 intel , AMD 這樣的 strong memory model cpu , 可以保障 store/store , load/load 的 memory fence ,

所以 在上面開發 的 programmer 較少接觸 memory fence 領域 , 以下是一個例子 : x,y,z=0 initially ~~

thread1 :

x=1;

y=1;

z=1;

Thread2 :

如果 z ==1 是否 x and y 一定是 1 ?

如果是 intel ,AMD 的 cpu ,  無需加上 memory fence 肯定可以保證  x and y = 1 , 除非 compiler 作了手腳 ,

compiler 可以用 volatile 去預防 ,  strong memory model cpu 可以做到 store/store , load/load 的一致性 ,

這是因為  cpu 使用了 FIFO 的 writebuffer ,  所以 當 cache line 不在此 cpu core 時 , 可以先將 store 運算先存放於

writebuffer , 如果要將任何 writebuffer 資料 pass 給其他 core ,就必須依照 FIFO 順序 寫出 , 所以 store/store

的順序就會如 programmer 預期般執行了 !!!!

 

沒有這樣功能的 cpu ,  在處理 concurrency 程式時 必須注意到使用 memory fence 來控制執行順序 ,

否則上述利子就可能出乎意料之外 !!!!

 

最後 , 不厭其煩的例子 : x , y =0 initially

thread1 :

x = 1 ;

r1= y ;

 

thread2:

y=1 ;

r2=x ;

 

就算是 intel cpu ,  這個答案也可能是 r1==0 && r2 ==0  !!  這是因為 intel 並無 store/load  memory barrier ,

只要 thread1 發生 先將 y 的值 load 進來(此時為 0) , 再執行  x=1; r1=y ;

thread2 發生先將 x 值 load進來(此時為 0) , 再執行 y=1; r2 =x ;

這樣就可以發生  r1==0 && r2==0 的情況,   如果你不想使用 lock or Read-Modify-Write ,Compare-And-Swap

這些有 memory barrier 功能的物件 ,  那麼在 intel  上面得注意 store/load barrier 問題 ,

幸好這樣寫法不常見 , 知道有這回事即可 !!!!

 

 

 

 

arrow
arrow
    全站熱搜

    hedgezzz 發表在 痞客邦 留言(0) 人氣()