簡體   English   中英

C ++中std :: memory_order到底提供了哪些柵欄?

[英]Which fences exactly provided by std::memory_order in C++?

據我所知std :: memory_order枚舉提供了內存隔離,但我需要確定每個std :: memory_order枚舉元素提供的隔離。 下面我解釋一下我理解的每個std :: memory_order枚舉元素:

  1. std :: memory_order_relaxed-沒有提供圍欄
  2. std :: memory_order_acquire-LoadLoad_LoadStore
  3. std :: memory_order_release-LoadStore_StoreStore
  4. std :: memory_order_consume-通常等於memory_order_acquire
  5. std :: memory_order_acq_rel-LoadLoadLoadStore_LoadStoreStoreStore ???
  6. std :: memory_order_seq_cst-StoreLoad_StoreLoad ???

關於前四個要素,我不確定。 但是關於最后兩個元素,我什么都不知道。

有人知道嗎?

另外,我需要知道在使用std :: atomic或std :: atomic_flag時,編譯器將內存置於何處?

據我了解,使用帶有原子的籬笆意味着應用籬笆並執行操作 我對嗎? 例如:

atomic.load(std::memory_order_acquire);

意味着應用memory_order_acquire柵欄並自動加載數據?

有人知道嗎?

當然,有各種各樣的資源,例如C ++ Reference

memory_order_relaxed —寬松的操作:沒有對其他讀取或寫入施加任何同步或排序約束,僅保證此操作的原子性。

memory_order_consume —具有此內存順序的裝入操作在受影響的內存位置上執行消耗操作:在此裝入之前,不能根據當前裝入的值對當前線程中的任何讀取或寫入進行重新排序。 在釋放相同原子變量的其他線程中寫入與數據相關的變量在當前線程中可見。 在大多數平台上,這僅影響編譯器優化。

memory_order_acquire —具有此內存順序的裝入操作在受影響的內存位置上執行獲取操作:在此裝入之前,無法對當前線程中的任何讀取或寫入進行重新排序。 在其他線程中釋放相同原子變量的所有寫操作在當前線程中可見。

memory_order_release —具有此內存順序的存儲操作執行釋放操作:在此存儲之后,無法對當前線程中的任何讀取或寫入進行重新排序。 當前線程中的所有寫操作在獲取相同原子變量的其他線程中可見,而將依賴項帶入原子變量的寫操作在消耗相同原子的其他線程中可見。

memory_order_acq_rel —具有此內存順序的讀-修改-寫操作既是獲取操作,也是釋放操作。 在此存儲之前或之后,無法對當前線程中的任何內存讀取或寫入進行重新排序。 修改之前,其他線程中釋放相同原子變量的所有寫操作都是可見的,而修改在其他獲得相同原子變量的線程中可見。

memory_order_seq_cst —具有此內存順序的裝入操作執行獲取操作,存儲執行釋放操作,讀-修改-寫操作同時執行獲取操作和釋放操作,並且存在一個總順序,其中所有線程都觀察到所有修改以相同的順序。

還請查看Herb Sutter撰寫的atomic <>武器介紹 ,其中有很多解釋。

另外,我需要知道編譯器將內存圍起來的位置

這是依賴於體系結構的。 在某些體系結構上,它是無操作的;在某些體系結構上,它是指令的前綴;在某些體系結構上,它將是加載/存儲之前/之后的特殊指令。

有一篇名為“內存屏障:軟件黑客的硬件視圖”的論文 ,如果您有興趣,可以分析許多體系結構上的障礙。

例如: atomic.load(std::memory_order_acquire); 意味着應用memory_order_acquire柵欄並自動加載數據?

這也依賴於體系結構,但是對於獲得障礙,我會說相反:我們加載一個變量,然后確保在加載之前沒有進一步的讀/寫操作,即放置柵欄。

但是在某些平台上,它可能是單處理器指令。 例如,在ARM上有加載獲取(LDA)和存儲釋放(STL)指令。

暫無
暫無

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

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