簡體   English   中英

C++11 原子:std::memory_order 代碼是否可移植?

[英]C++11 atomic: is std::memory_order code portable?

在像std::atomic::compare_exchange這樣的函數中,有像std::memory_order_releasestd::memory_order_relaxed這樣的運行時參數。 http://en.cppreference.com/w/cpp/atomic/atomic/compare_exchange

我不確定這些內存順序標志是否保證存在於所有類型的 CPU/架構師中,如果某些 CPU 不支持某個標志,該標志會導致崩潰還是? 似乎其中一些標志是為英特爾安騰等設計的,不確定與std::memory_order相關的代碼是否可移植。

你能給一些建議嗎?

通常,無論您要求什么,編譯器都可以自由地僅提供最強的內存保證。

在某些平台上,有足夠的寬松保證。 並非所有平台都支持這些寬松的保證。 在這些平台上,編譯器必須提供更嚴格的保證。

因此它們是可移植的,因為當您要求特定保證時,符合標准的編譯器必須提供該保證或更好

請注意,值得關注的不僅僅是硬件。 某些優化和重新排序可能合法與否,取決於您要求的內存順序保證。 我不知道任何依賴於此的編譯器,但我不是編譯器專家。

C++ 標准確實有所謂的“獨立”實現的概念,它可以支持標准庫的一個子集。 但是,它還定義了即使是獨立的實現也必須支持的最低限度的功能。 在該列表中是整個<atomic>標頭。

所以是的,實現必須支持這些。

但是,這並不意味着特定標志將完全執行且僅執行該標志所描述的操作。 標志代表最小內存屏障,保證可見的特定事物。 如果硬件實現沒有較低層的內存屏障,即使對於不需要它的標志,實現也可能會發出完整的內存屏障。

所以你應該按照標准寫代碼,讓編譯器整理出細節。 如果證明它在平台上效率低下,您可以檢查組件以查看是否可以改進問題。

但是要回答您的主要問題,是的,基於原子的代碼是可移植的(模編譯器錯誤)。

在實踐中,消費語義總是被當前的編譯器加強以獲取,因為事實證明如果不這樣做就很難安全地實現。 要么:

  • 該架構在所有負載上提供獲取,然后負載消耗與負載獲取執行相同的操作,與負載放松相同:沒什么特別的(如 x86);
  • 該架構甚至在依賴訪問時也需要獲取屏障(非常非常罕見,可能只有 DEC Alpha):然后編譯器將在消費時使用獲取屏障;
  • ISA 保證了 asm 中加載的依賴順序,但完全獲取需要一個屏障。 (這就是consume試圖向程序員公開的內容)。 編譯器應該為您提供避免邏輯(不是瘋狂)使用消費障礙的好處

    • 要么編譯器嘗試這樣做,但它很棘手並且在編譯器后端優化中斷的某些極端情況下失敗(前端通常不會與其后端進行足夠的通信,以避免這些只是為了消費);
    • 或者您不信任編譯器,將優化設置為零,這甚至不能保證后端隱式完成的任何微不足道的優化都不會破壞消耗(並使性能變得非常糟糕);
    • 或者編譯器作者不關心效率,或者知道他們無法提供可靠的工作,因此他們提供了獲取,這在語義上是正確的但實際上效率較低,而不是標准的意圖。

(而且 C++ 的消費語義很瘋狂。它是 C++ 中最不一致的部分之一,它告訴了你很多。)

暫無
暫無

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

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