簡體   English   中英

獲取/發布語義重新排序

[英]Acquire/Release semantics reordering

基於C ++ 11獲取/發布語義,我有以下問題:

獲取語​​義定義:編譯器/ CPU不應重新排列在獲取之后發生的讀取,而不是在獲取之前發生的讀取。 1.但是,能否將在acquire語句之后發生的寫入重新排序為在Acquire之前發生的寫入?

Release語義定義:編譯器/ CPU不應將Release之前發生的寫入重新排序為Release以后。 2.但是,是否可以將在Release語句之前發生的讀取重新排序為Release之后的讀取?

例:

atomic<int> i = 0, j = 0, x = 0;

i = 0;

j = x;

i = 20;
  1. 編譯器/ CPU是否將上述內容重新排序(優化)為以下內容:

    原子i = 0,j = 0,x = 0;

    我= 20;

    j = x;

  2. 但是,如果我們使用獲取負載,則編譯器/ CPU將避免重新排序對i的寫入(i = 20)?

    原子i = 0,j = 0,x = 0;

    i = 0;

    原子j = x.load(memory_order_acquire);

    我= 20;

我認為您切換了獲取/發布語義。
來自cpp參考

memory_order_acquire:[...] 此加載之前,無法重新排序當前線程中的任何讀取。

memory_order_release:[...] 此存儲之后 ,當前線程中的所有寫操作都無法重新排序。

關於您的問題:

但是它可以將在acquire語句之后發生的寫入重新排序為在Acquire之前發生的寫入嗎?
但是,它可以將在Release語句之前發生的讀取重新排序為Release之后嗎?

通常,是的,只要在不重新排序的情況下原樣攜帶代碼效果,編譯器和CPU就可以對指令重新排序,以使程序運行更快。 這就是為什么如果需要嚴格排序的原因,我們顯式使用原子+內存順序和鎖。

阻止CPU /編譯器重新排序的一個普遍問題是依賴性 ,例如,請看以下示例:

int a = atomicA.load(std::memory_order_relaxed);
a += 10;
atomicB.store(a,std::memory_order_relaxed);

盡管代碼中沒有明確規定排序(隨意的原子=如您所願的重新排序), atomicB通過a承載了atomicA依賴性,並且在依賴性的情況下(即使代碼中未明確規定排序),執行也必須順暢進行在這種情況下,以一種保持該依賴性的方式,不必在加載之前對商店重新排序。

暫無
暫無

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

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