原子操作 memory order 設定
這個設定可以限制 CPU 亂序執行的執行順序,簡單說明如表:
| 設定值 | 讀 | 寫 | 順序 |
| relaxed | O | O | 不影響 |
| acquire | O | X | 後面的程式要等這行執行完了才會執行, 即後面的程式不會早於此操作執行。 |
| release | X | O | 前面的程式要都執行完了才會執行後面的程式, 即前面的程式不會晚於此操作執行 |
| acq_rel | O | O | 等同 acquire + release |
| seq_cst | O | O | 視操作類型加上 acquire, release, acq_rel 其一,並依序向其他線程同步 |
| consume | O | X | 等同 acquire,但只向與該變數有關的線程同步 據說編譯器沒實作這東西,沒驗證是否為真 |
整理資訊原文
- memory_order_relaxed:純原子操作,不影響順序
- memory_order_acquire:只能用於取值,且確保後面變數的讀寫操作不會再取值前開始(即保證後面的變數操作不會被往前排)
- memory_order_release:只能用於寫值,寫值前會確保前面變數的讀寫操作都完成了(即保證前面的變數操作不會被往後排)
關聯點:使用 memory_order_acquire 的線程會向使用 memory_order_release 且同一個原子變數的線程同步所有更動(包含非原子變數)
重點:只有相關的線程才會同步,其他線程不一定同步
memory_order_acq_rel:即把兩個動作變為一個原子操作,所以前面的變數操作不會往後跑,反過來也一樣。
做完的同時,變數也同步完了 - memory_order_seq_cst:視操作附有 memory_order_acquire, memory_order_release, memory_order_acq_rel 三種特性之一,且依序向所有線程同步!
- 最後是 memory_order_consume,基本上與 memory_order_acquire 一樣
但是只對相依的變數做線程同步!
所以在變數運算上如果沒有與該原子變數關聯(比如作為運算參數),那就不會被同步!
Leave a Comment