2016-07-22 37 views
2

我想以原子方式和非原子方式操縱相同的內存位置。通過聯合對原子進行非原子訪問

讓我們假設我有一個簡單類型的工作,就像一個int,尤其是std::atomic<T>::is_lock_free()回報true,那sizeof(T) == sizeof(std::atomic<T>)

我認爲,一個reinterpret_cast應該工作:

std::atomic<int> x; 
int& xx = reinterpret_cast<int&>(x); 

N4013解釋說,這可能會在編譯器混淆基於類型的別名分析,因此是不可靠的。

我的問題是:union怎麼辦?如果我創建以下內容:

union AtomicInt 
{ 
    int nonatomic; 
    std::atomic<int> atomic; 
}; 

AtomicInt x; 
x.nonatomic = 5; 
x.atomic.compare_exchange_weak(...); 

這是否按預期工作?我能以原子方式和非原子方式操作相同的內存嗎?


搶佔約代替非原子操作的使用load(std::memory_order_relaxed)建議, 我試過在this answer的建議,一個相關的問題,但它減緩我的代碼下降了50%。

+0

是什麼讓你認爲'std :: atomic '在內部與'int'相同? –

+0

如果它無鎖且尺寸相同,我很難想象它會有所不同。 – foxcub

+0

我也是,但我一直在這樣的事情錯了。我敢說,你會得到的最好結果是它看起來工作得很好 - 直到它沒有。你永遠不會失敗,甚至不會注意到它。訪問存儲的值將以完全不同的方式完成。例如,通過「int」所做的更改可能對另一個CPU上運行的線程不可見。看看你的編譯器發出的指令,看看它是否應該工作。充其量,我會說「工作」將是平臺依賴的UB。但出於性能方面的原因,您可能需要這樣做。 –

回答

0

無鎖原子基元用於高度擁塞的併發。如果擁擠程度很高,並且您開始將原子變量用作非原子,那麼如果在特定架構intatomic<int>具有相同的佈局,您肯定會引入錯誤甚至

如果您的擁堵率低,但在某些情況下需要特殊排序,則應使用鎖定。

+2

我永遠不會開始在並行執行過程中使用我的變量作爲非原子。我想在原子執行之前的串行執行期間將它們用作非原子。 – foxcub

+0

那麼爲什麼不只在它之前使用另一個(非原子)變量,並在稍後將它分配給一個原子? – Dutow

+1

我不想複製(和內存)的開銷。 – foxcub