推 stupid0319: 看不太懂,x應該是同一塊記憶體,怎會有flush的問題 10/14 19:10
→ Lipraxde: 恩...應該 compiler 優化有問題才會像你說的這樣啊?有 10/14 20:14
→ Lipraxde: 沒有前後文? 10/14 20:14
→ descent: 他後面有提到 volatile 和 memory barrier, page 29 10/14 20:30
※ 編輯: Arton0306 (36.227.78.148), 10/14/2018 20:36:06
→ Arton0306: 我說flush是指寫出去到memory的意思 10/14 20:38
→ Arton0306: 29頁那個cpu自行換序的問題 我試過真的會發生 10/14 20:40
→ Arton0306: 但28頁這個我沒遇過 10/14 20:40
→ Arton0306: 再看一次 好像真的如同L大說的 這段是在講compiler的問 10/14 20:46
→ Arton0306: 題 所以compiler看到mutex夾住的要小心 應該是這意思@@ 10/14 20:48
→ Arton0306: 我原本以為它是說code有問題 冏XD 10/14 20:54
→ stupid0319: 如果是留在暫存器中,也不能算做完x++吧 10/14 21:33
→ stupid0319: 書上意指lock前就把x值存進暫存器? 10/14 21:38
我想它這段真的是沒有寫很清楚,以下是我的理解:
它說「落後的編譯器技術已經無法滿足日益增長的並行需求,很多看似無錯的程式碼
在最佳化和並行面前又產生了麻煩,最簡單的例子…(就是我上面寫的code)」
也就是它舉了一個compiler最佳化出bug的例子,
在它的例子中
x+1的值留在register中,不是lock前就存進暫存器,
而是因為有可能之後會再用到,這樣比較快
singlethread是可以這麼做,
但在multithread的情況下,這樣的最佳化是compiler的bug
而它28頁最下方和29頁的例子是code真的有問題 compiler不可能解決
2個例子擺在一起容易誤會
※ 編輯: Arton0306 (36.227.78.148), 10/14/2018 23:09:24
→ stupid0319: 唉,連記憶體到CPU暫存器的時間也要省 10/14 23:38
推 Bencrie: 存取暫存器的時間遠小於記憶體啊 XD 10/15 01:19
→ PkmX: 現在的C/C++有規範不同thread之間的memory model 10/15 02:18
→ PkmX: 以std::mutex來說 unlock "synchronizes-with"下一個lock 10/15 02:28
→ PkmX: unlock前的side effects必須讓lock後的code看到 10/15 02:28
→ PkmX: 如果編譯器沒有把x的值寫回記憶體的話就是做錯了 10/15 02:28
推 steve1012: c++ 11以後要follow sequential consistency. 10/15 13:05
感謝 原來後來加進standard了
想到一段以前寫過的code
bool isStop = false; // global var
thread 1 thread 2
while (!isStop) { do something...
do something isStop = true
}
也就是thread1 重複做某件事 直到thread2設定了isStop的flag
例如用在gui取消/中斷某個耗時的計算
現在回想起來
isStop沒有用lock包起來是否有問題??
如果加上volatile 而沒有lock 這樣是否安全?
※ 編輯: Arton0306 (36.227.78.148), 10/16/2018 01:59:34
→ PkmX: seq_cst是atomic operation之間預設才有 10/16 09:44
→ PkmX: 像上面那種bool isStop兩個threads同時寫還是UB 10/16 09:44
→ PkmX: 除非你有用mutex等東西讓兩個讀寫有"happens-before"的關係 10/16 09:45
推 jun0325: 用volatile應該就會讓compiler每次都會寫回memory了吧 10/16 22:12
→ PkmX: 照標準volatile和thread之間的synchronization是沒有關係的 10/17 10:47
→ PkmX: 而且volatile也不一定是atomic access 10/17 10:48
我發現我原本寫的thread 1的while (isStop)寫錯了
改了while (!isStop) 才對
我上面的例子只有2個thread,只有thread2才會去寫isStop
※ 編輯: Arton0306 (220.136.4.208), 12/07/2018 01:38:57