簡體   English   中英

C++中的release fence調用go究竟是什么時候從聲明變成保證?

[英]When exactly does a release fence call in C++ call go from being a statement to being a guarantee?

根據 Jeff Preshing 博客中的一篇文章:

釋放柵欄可防止 memory 對按程序順序在其之前的任何讀取或寫入與按程序順序在其之后的任何寫入進行重新排序。

他還有一篇很棒的帖子,在這里解釋了發布圍欄和發布操作之間的區別。

盡管這些博客文章中有明確的解釋,但我仍然對如何解釋釋放柵欄調用感到困惑,例如std::atomic_thread_fence(std:memory_order_release); 就 memory 操作重新排序與提供釋放柵欄保證的潛在柵欄機制而言。

編譯器是否必須保證在編譯為機器代碼時避免在 fence 語句調用之前的線程中進行稍后寫入調用的可能性,而 CPU 在處理它時必須保證相同?

也就是說,fence調用go到底是什么時候從聲明變成了保證呢?

最重要的是,編譯器或 CPU 重新排序是否有可能將 fence 語句的程序順序之后的寫入操作重新排序,以便在該過程中的執行時位於 fence 之前?

編譯器是否必須保證在編譯為機器代碼時避免在 fence 語句調用之前的線程中進行稍后寫入調用的可能性,而 CPU 在處理它時必須保證相同?

必須禁用某些編譯器優化。 編譯器必須發出阻止某些 CPU 優化的代碼,包括必要的 CPU 防護指令。 這就是使它成為保證的原因...

編譯器或 CPU 重新排序是否有可能重新排序 fence 語句的程序順序之后的寫入操作,以在該過程中的執行時在 fence 之前?

帶有std::memory_order_releasestd::atomic_thread_fence防止在柵欄之前(程序順序中的“之前”)的加載和存儲被柵欄之后的任何存儲重新排序(后續加載可以在之前重新排序)。 在執行時,只要保證成立,可能不需要實際的 memory 屏障指令本身。

帶有std::memory_order_acquirestd::atomic_thread_fence防止柵欄之后(程序順序中的“之后”)的加載和存儲被柵欄之前的任何加載重新排序(較早的存儲可以在之后重新排序)。 在執行時,只要保證成立,可能不需要實際的 memory 屏障指令本身。

請注意,這分別比 std::atomic::store 和 std::atomic::load 更嚴格。

帶有std::memory_order_releasestd::atomic<T>::store防止之前的加載和存儲僅使用該特定存儲重新排序。 隨后的加載和存儲可以在之前重新排序。 從理論上講,這是一種傳統的單向發布。 (在實踐中,可能會使用比嚴格需要的更嚴格的同步。)

帶有std::memory_order_acquirestd::atomic<T>::load防止加載和存儲之后僅使用該特定加載進行重新排序。 較早的加載和存儲可以在之后重新排序。 從理論上講,這是一種傳統的單向獲取。

暫無
暫無

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

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