中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

?C++的memory order怎么理解

發布時間:2021-11-26 13:54:28 來源:億速云 閱讀:203 作者:iii 欄目:大數據

這篇文章主要講解了“C++的memory order怎么理解”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“C++的memory order怎么理解”吧!

Key Points:

  • 要從"防止編譯器重排"與"防止CPU亂序"兩個角度去理解 memory_order
  • release semantics 一言以蔽之,一般表示 "最后 Store"
  • acquire semantics     一言以蔽之,一般表示 "最先 Load"
  • 注意 x86_64 CPU 一般^1都滿足 strong memory model 特性:CPU 四種可能發生的亂序中,只允許StoreLoad亂序(或稱為StoreLoad重排)

?C++的memory order怎么理解

 

1)與 atomic 連用

memory_order_relaxed:atomic variable 的 relaxed 操作和普通變量普通操作有何區別?

  • 普通變量的SL操作并不保證原子性,而 atomic 變量的所有操作都是保證原子性的。(TODO: 甚至不會被中斷打斷?)
  • x86_64 實測:atomic 變量結合任意 memory_order 都能有效防止編譯器重排。

memory_order_consume:所有后續 data-dependent 的 S/L 操作禁止被 re-order 到本 L 前面。和 release-S 連用。

memory_order_acquire:所有后續 S/L 操作禁止被 re-order 到本 L 前面。和 release-S 連用。

  • acquire 操作強調本 L 一定是"最先 Load"。

x86_64 實測:

  • a.load(acquire/relaxed) 產生的機器碼相同。猜測是由于 x86_64 的 strong-memory-model 性質,禁止     L-S 和     L-L 重排,其任何 Load 都具有 acquire 語義。
  • UB 操作:a.store(acquire),則機器碼會在 S 后面添加一個 mfence。此時實際產生的語義為:所有后續 S/L 操作禁止被 re-order 到本 S 前面。猜測是由于 x86_64 CPU 允許 S-L re-order,那么要保證此 S 后面的 S/L 不被重排到本 S 前,那么只能加入 fence 指令。
  • UB 操作:a.load(release) 產生的機器碼等同于 a.load(acquire)。(注意并不符合類似 S-release 的語義 "所有前面 S/L 操作禁止被 re-order 到本 L 后面,如果要符合的話必須在本 L 前面加 mfence)"
  • UB 操作:a.load() 接所有 memory_order 都等效于 a.load(acquire),即編譯產生同樣的機器碼。

memory_order_release:所有前面 S/L 操作禁止被 re-order 到本 S 后面。和 acquire/consume-L 連用。

  • release 操作強調本 S 操作一定是"最后 Store"。

x86_64 實測:

  • a.store(release/relaxed) 產生的機器碼相同。猜測是由于 x86_64 的 strong-memory-model 性質,禁止 S-     S 和 L-     S 重排,其任何 Store 都具有 release 語義。
  • UB 操作:a.store(acquire/consume/acq_rel/seq_cst) 產生的機器碼相同,都是在本 S 后面加入一個     mfence 指令。猜測是由于 x86_64 中,只需要在 S 后面加一個 mfence,該 S 就能同時滿足"本 S 前所有的 S/L 禁止被重排到本 S 之后(即 release 語義)"與"本 S 后所有的 S/L 禁止被重排到本 S 之前(類似 L-acquire 語義)"的兩個條件

memory_order_acq_rel:適用于RMW操作。

  • 1)本線程所有 S/L 操作(無論前后)禁止被 re-order 到本 S 前或后。
    • 為什的只提到S?(TODO: 這個RMW操作一定是保證原子性的嗎?)
    • 其實是只需要關心 S 即可。因為RMW操作的特性類似一個 LS 操作,這里 S 已經作為了同步點,本線程 L 前的 S/L 即使重排也只能重排在本 L 后且本 S 前,即使發生這種重排也是沒有關系的。而本 S 后所有的 S/L 都不可被重排到本 S 前,這樣就間接保證了不可被重排到本 L 前,從而也保證了 acquire 語義。
  • 2)執行了相應 release 操作的其他線程,其 release 前的所有 S 一定發生在本 S 前。
    • 這句話其實暗含了其他線程造成的該原子變量本身的 S 一定是發生在本 L 前的。因為如果其他線程對該原子變量的改動還沒有被本線程觀察到的話,可以認為其他線程并沒有寫它,也就不存在同步問題。既然觀察到了變化,那么這個變化伴隨的更改順序關系才需要被討論。
    • 由于 S 比 L 慢,因此這個語義只要求其他線程被 release 的 S 一定是發生在本 S 之前就可以,沒必要嚴格到必須發生在本 L 之前,那樣效率會變低。不過這個要求已經比單純的 acquire 嚴格了,即要求其他線程被 release 的 S 可以發生在本 L 后但必須發生在本 S 前,而單純的 acquire 只暗含本 L 之后,就能看到相關線程所有被 release 的 S 了
  • 術語情景:x=1; y.store(1, release); 此時稱為 x=1 和 y=1 這些 S 最后執行了 release 操作。或者說 x=1 和 y=1 都是被該線程 release 的 S 操作,且同步點是 Y。

memory_order_seq_cst

  • 對于 L 執行 acquire 語義
  • 對于 S 執行 release 語義
  • 對于 RMW 執行 acq_rel 語義,并且對所有線程執行了 seq_cst 操作的 S,都存在一個 TSO
    • TSO:Total Single Order,所有線程觀察到的 S 順序都是一樣的?
  • x86_64 實測:
    • seq_cst 與 load 操作連用時,與所有 memory_order 都等效。即編譯產生同樣的機器碼。
    • seq_cst 與 store 操作連用時,與 acquire/consume/acq_rel 等效。

感謝各位的閱讀,以上就是“C++的memory order怎么理解”的內容了,經過本文的學習后,相信大家對C++的memory order怎么理解這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

c++
AI

明水县| 大余县| 晴隆县| 营山县| 宝清县| 阿城市| 宝丰县| 葫芦岛市| 大庆市| 柳江县| 健康| 大悟县| 子长县| 日照市| 泸州市| 青川县| 栾城县| 武穴市| 濮阳县| 镇原县| 凤台县| 东丰县| 木兰县| 东乌珠穆沁旗| 积石山| 偏关县| 五莲县| 桓台县| 太仓市| 达拉特旗| 勐海县| 石景山区| 综艺| 垦利县| 体育| 齐河县| 清原| 肥东县| 惠东县| 洪洞县| 苍南县|