2012-11-20 27 views
2

我有一個內存變量在線程A中更新並在其他線程中讀取。讀者只關心該值是否爲非零。我保證一旦數值遞增,它就不會回到零。 如下優化是否有意義?換句話說,在讀者方面,一旦我的條件得到滿足,我就不需要「圍欄」。C++原子加載排序效率

std::atomic<int> counter; 

writer: 
increment() 
{ 
    counter.store(counter+1, std:memory_order_release) 
} 

reader: 
iszero() 
{ 
    if (counter.load(std::memory_order_relaxed) > 0) return false; 
    // memory fence only if condition not yet reached 
    return (counter.load(std::memory_order_acquire) == 0); 
} 
+1

計數器可能會回到零。 –

+0

在reader :: iszero()中有一個線程局部布爾值並將其設置爲true,以便您第一次從計數器獲得非零值。如果是這樣,立即返回false。只有當它仍然是錯誤的,請檢查櫃檯。 –

+0

讀者多久訪問一次?這似乎是不成熟的優化。 –

回答

2

首先,如果你不使用默認的(順序一致)原子能,測量你的應用程序的性能真正嘗試,異形的,並顯示他們觀察到導致性能問題,我建議義無反顧現在。

但是,如果你實在需要開始推理輕鬆原子能...


這是不能保證你所期望的,但它幾乎肯定會在x86工作。

我猜你正在用這個來防範其他一些非原子數據的發佈。

在這種情況下,你需要保證如果您在讀取器線程讀取一個非零值,然後各種其他副作用,以非原子存儲單元(即初始化你的數據發佈)在商店之前在作者線程中發佈的內容將對讀者線程可見。

讀取非零與std::memory_order_relaxed同步std::memory_order_release存儲,所以你的代碼上面沒有這個保證。

爲了得到我所描述的行爲,您需要使用std::memory_order_acquire。如果你在x86上,那麼獲取不會產生任何內存圍欄指令,所以它的性能與memory_order_relaxed不同的唯一方法是通過防止一些編譯器優化。

+0

首先,就我而言,只有當我關心原子位置的新的非零值時,我才關心非atmoic位置。我檢查了x86指令 - 你說得對,在獲取和放寬之間似乎沒有區別 - 都使用mov。我只需要保證所有商店都是按順序看到的。我希望我可以通過發佈獲得更輕的指令集,但似乎並非如此。 – excalibur