首頁  >  文章  >  後端開發  >  為什麼使用“memory_order_seq_cst”來設定停止標誌,而使用“memory_order_relaxed”來檢查它?

為什麼使用“memory_order_seq_cst”來設定停止標誌,而使用“memory_order_relaxed”來檢查它?

Linda Hamilton
Linda Hamilton原創
2024-11-18 03:11:02304瀏覽

Why use `memory_order_seq_cst` for setting the stop flag but `memory_order_relaxed` for checking it?

為什麼在檢查 memory_order_relaxed 時使用 memory_order_seq_cst 進行停止標誌設定?

在關於原子操作的討論中,Herb Sutter 提供了一個範例用法原子,包括停止標誌機制:

  • 一個主執行緒啟動多個工作執行緒。
  • 工作執行緒不斷檢查停止標誌:

    while (!stop.load(std::memory_order_relaxed))
    {
      // Do stuff.
    }
  • 主執行緒最終設定 stop = true 和order=seq_cst,然後加入

在儲存作業上不使用relaxed的原因

儘管Herb 建議因為最小而使用memoryorder__relaxed 來檢查標誌是可以延遲接受的,但即使優先考慮延遲,採用更嚴格的記憶體順序也沒有明顯的效能優勢。

背後的原因是否在儲存作業中使用寬鬆尚不清楚,可能是由於疏忽或個人偏好。

延遲注意事項

ISO C 標準不會強制執行儲存的特定時間範圍可見性或提供如何影響它的指導。這些規定適用於所有原子操作,包括寬鬆的。但是,鼓勵實現在合理的時間範圍內使原子加載可以存取存儲值。

實際上,具體延遲由實現決定,硬體快取一致性機制通常允許在最佳情況下在數十奈秒內實現可見性。情境場景和接近最壞情況場景中的亞微秒間隔。

內存順序含義

存儲或加載操作的不同內存順序不會實時加速存儲,它們只是控制後續操作是否可以在存儲仍處於掛起狀態時變成全局可見。

本質上,更強的訂單和障礙並不會絕對加速事件發生,而是推遲其他事件,直到儲存或載入完成。這對於所有現實世界的 CPU 都是如此,它們努力使儲存對其他核心即時可見。

因此,增加記憶體順序(例如使用 seq_cst)可確保對停止標誌的變更立即對工作線程可見線程,並保證快速關閉。但是,它不會影響實際的可見性延遲。

寬鬆檢查的好處

使用memory_order_relaxed 進行檢查操作有幾個優點:

  • 最小化指令級和內存級並行性指令級和內存級並行性指令級和內存級並行性瓶頸。
  • 減少了指令級並行受限架構的開銷,特別是那些具有高成本障礙的架構。
  • 消除了因對載入結果的分支錯誤預測而造成的浪費工作。

其他注意事項

Herb 正確地辨識出,由於 thread.join 提供的同步,使用relaxed 作為髒標誌也是可以接受的。但需要注意的是,dirty 需要原子性來防止同時寫入相同的值,這在 ISO C 標準下仍然被認為是資料競爭。

綜上所述,在使用 memory_order_seq_cst 設定停止標誌時可以確保立即執行對於工作執行緒的可見性,與放鬆載入操作相比,這樣做沒有任何效能優勢。 memory_order_relaxed 在指令級並行性和記憶體頻寬利用率方面具有優勢,使其成為此類場景的首選。

以上是為什麼使用“memory_order_seq_cst”來設定停止標誌,而使用“memory_order_relaxed”來檢查它?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn