2013-02-08 59 views
4

我在閱讀Anthony Williams的C++ Concurrency in Action。目前我在他desribes memory_order_consume點。C++ memory_order_consume,kill_dependency,dependency-ordered-before,與...同步

該塊之後有:

現在,我已經覆蓋了內存排序的基礎,它的時間來看看 更復雜的部件

這讓我害怕一點點因爲我沒有完全理解幾件事情:


如何依賴性排序之前不同步與同步?他們都創造了發生之前的關係。什麼是確切的區別?


我感到困惑下面的例子:

int global_data[]={ … }; 
std::atomic<int> index; 
void f() 
{ 
    int i=index.load(std::memory_order_consume); 
    do_something_with(global_data[std::kill_dependency(i)]); 
} 

是什麼kill_dependency究竟怎麼辦?它殺死哪個依賴關係?在哪些實體之間?以及編譯器如何利用知識庫?


memory_order_consume的所有居民都可以安全地用memory_order_acquire替換嗎?即所有的感官都更嚴格嗎?


在清單5.9,可我安全地

int data[5] 

更換

std::atomic<int> data[5]; // all accesses are relaxed 

?即可以獲取並釋放用於同步對非原子數據的訪問嗎?


他描述了放寬,獲取和釋放一些例子與男孩在房間裏。是否有一些類似的seq_cst簡單描述和消耗?

+0

的可能重複[這是什麼\'的std ::殺\ _dependency \'做的,我爲什麼要使用它?(http://stackoverflow.com/questions/7150395/what-does-stdkill-依賴關係做和爲什麼要我想要使用它) – Cubbi 2013-02-09 05:03:10

+0

@Cubbi,我看到它 - 還有另一個例子。 – qble 2013-02-09 07:53:35

回答

2

dependency-ordered-before如何區別於同步-with?

從1.10/10開始:「[注意:關係」在依賴關係排序之前「類似於」同步關係「,但使用釋放/消耗來代替釋放/獲取。

kill_dependency究竟幹什麼?

一些編譯器進行數據依賴性分析。也就是說,他們追蹤變量中的值,以便更好地找出需要同步的內容。 kill_dependency告訴編譯器不要進一步追蹤,因爲編譯器不理解的代碼中有某些事情發生。

memory_order_consume的所有使用者都可以安全地用 memory_order_acquire替換嗎?即所有的感官都更嚴格嗎?

我想是這樣,但我不能肯定。

+1

'std :: kill_dependency'告訴編譯器從可能的內存順序依賴樹中移除該元素。 – inf 2013-02-08 19:31:33

+0

「kill_dependency告訴編譯器不要跟蹤」 - 是的,我明白這一點,但我不明白確切的機制和所有影響。 「我認爲是這樣,但我不確定。」 - 我也是。 – qble 2013-02-08 19:53:02

5

至於倒數第二個問題,答案需要一點更多的解釋。有三樣東西可以去錯了,當多個線程同時訪問相同的數據:

  1. 系統可能切換線程在讀的中間或寫,產生結果的一半一個值和另一半。

  2. 編譯器可能會左右移動代碼,在假定沒有其他線程查看的是所涉及的數據。

  3. 處理器可以被保持在其本地高速緩存的值,而不改變值或重新閱讀之後另一個線程改變在主存儲器中的值之後,更新主存儲器。取決於存儲器順序參數,也許3以及

存儲器地址順序僅 3.原子功能地址1和2,以及,。所以memory_order_relaxed的意思是「不要打擾編號3.代碼仍然處理1和2.在這種情況下,你會使用獲取和釋放,以確保正確的內存順序。

2

memory_order_consume要求原子操作發生 - 之前所有那些數據依賴於它。數據依賴性是任何依賴性,你不能在不使用該數據計算表達式。例如,在x> Y,沒有辦法而無需首先以評估X->ý非原子操作評估x。

kill_dependency是一個獨特的函數,所有其他的函數對它們的參數都有一個數據依賴關係,Kill_dependency顯式地沒有,當你知道數據本身已經同步了,但是你需要獲得的表達式到數據可能不會同步識別的。在你的例子中,do_something_with允許假定任何緩存的globalldata [i]的值可以安全使用,但是我本身必須實際上是正確的原子值。

memory_order_acquire嚴格爲更強如果對數據的所有更改都通過匹配的memory_order_release正確釋放。