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 問題 ,
幸好這樣寫法不常見 , 知道有這回事即可 !!!!
留言列表