簡體   English   中英

C++11 是否保證釋放柵欄和消費操作之間的內存排序?

[英]Does C++11 guarantee memory ordering between a release fence and a consume operation?

考慮以下代碼:

struct payload
{
    std::atomic< int > value;
};

std::atomic< payload* > pointer( nullptr );

void thread_a()
{
    payload* p = new payload();
    p->value.store( 10, std::memory_order_relaxed );
    std::atomic_thread_fence( std::memory_order_release );
    pointer.store( p, std::memory_order_relaxed );
}

void thread_b()
{
    payload* p = pointer.load( std::memory_order_consume );
    if ( p )
    {
        printf( "%d\n", p->value.load( std::memory_order_relaxed ) );
    }
}

C++ 是否對線程 a 中的柵欄與線程 b 中的消耗操作的交互做出任何保證?

我知道在這個例子中,我可以用 store-release 替換柵欄 + 原子存儲並讓它工作。 但我的問題是關於這個使用圍欄的特殊情況。

閱讀標准文本我可以找到關於釋放柵欄與獲取柵欄的交互以及釋放柵欄與獲取操作的交互的條款,但沒有關於釋放柵欄和消費操作的交互的條款。

我認為,用獲取替換消耗將使代碼符合標准。 但據我了解處理器實現的內存排序約束,我應該只需要線程 b 中較弱的“消費”排序,因為內存屏障強制線程 a 中的所有存儲在存儲到指針之前可見,並且讀取有效載荷取決於從指針讀取。

標准是否一致?

您的代碼有效。

我知道在這個例子中,我可以用 store-release 替換柵欄 + 原子存儲並讓它工作。 但我的問題是關於這個使用圍欄的特殊情況。

具有寬松原子操作的柵欄比相應的原子操作更強 例如(來自http://en.cppreference.com/w/cpp/atomic/atomic_thread_fence ,注釋):

雖然原子存儲釋放操作可防止所有先前的寫入移動超過存儲釋放,但具有memory_order_release排序的atomic_thread_fence可防止所有先前寫入移動超過所有后續存儲。

盡管這顯然是意圖,但指定柵欄和原子操作的交互方式意味着僅官方支持列出的組合 (這種規范風格不僅冗長,難以閱讀,更難以轉化為有效的直覺,很容易使不完整。)

我在標准中看不到任何支持將消費操作與釋放屏障配對的內容,即使正常實現不可能不支持,除非在全局程序優化期間進行特殊努力以檢測該特定用例並故意破壞它

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM