為什麼在檢查 memory_order_relaxed 時使用 memory_order_seq_cst 進行停止標誌設定?
在關於原子操作的討論中,Herb Sutter 提供了一個範例用法原子,包括停止標誌機制:
工作執行緒不斷檢查停止標誌:
while (!stop.load(std::memory_order_relaxed)) { // Do stuff. }
在儲存作業上不使用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中文網其他相關文章!