內(nèi)存模型基本結(jié)構(gòu):對象和內(nèi)存位置
內(nèi)存順序
內(nèi)存模型關(guān)系
sequenced-before
表達(dá)式的評估順序,它只在單個(gè)線程中被考慮。如語句A && B中會先執(zhí)行 A,判斷為true后再執(zhí)行 B,更為詳細(xì)的定義以及規(guī)則可參考Order of evaluation
代碼的順序也可以理解為sequenced-before關(guān)系,最終執(zhí)行時(shí)滿足標(biāo)準(zhǔn)庫的 as-if 準(zhǔn)則即可
synchronizes-with
指不同線程在原子類型上的操作,如對同一個(gè)原子變量,T2 中的load synchronizes-with T1 中的store
carries dependency
即依賴關(guān)系
dependency-ordered before
即release-consume ordering
inter-happens-before
線程間的happens-before關(guān)系,它依賴于synchronizes-with關(guān)系或dependency-ordered before關(guān)系
happens-before
同一線程即sequenced-before關(guān)系,不同線程即inter-happens-before關(guān)系
原子操作的內(nèi)存順序
sequentially consistent ordering
順序一致順序,std:: memory_order_seq_cst,它是所有原子操作內(nèi)存順序參數(shù)的默認(rèn)值:
- 所有原子類型實(shí)例上的操作是順序一致的
- 所有線程都必須看到相同的操作順序
順序一致是最直觀的排序,但也是最昂貴的內(nèi)存順序,因?yàn)樗笏芯€程之間的全局同步。在多處理器系統(tǒng)中,這可能需要處理器之間相當(dāng)密集和耗時(shí)的通信
另外可以參考有關(guān)sequential和order的理解,簡單來講sequential是一個(gè)接一個(gè)的意思,順序執(zhí)行,沒有重疊;order指經(jīng)過一定的調(diào)整,讓某樣?xùn)|西按照一定的規(guī)則變得有序;sequential order 就是指讓操作一個(gè)接一個(gè)的排列,并且沒有重疊
release-acquire ordering
釋放-獲取順序,指定std::memory_order_acquire內(nèi)存順序的原子載入(load)是獲取(aquire)操作,指定std::memory_order_release內(nèi)存順序的原子存儲(store)是釋放(relase)操作,指定std::memory_order_acq_rel內(nèi)存順序的原子的讀-修改-寫(如fetch_add()、exchange())是獲取操作 、釋放操作或兩者兼?zhèn)?/p>
當(dāng)兩個(gè)線程 T1、T2 滿足釋放-獲取順序時(shí),T2 中原子載入(load)操作完成后,T2 中后續(xù)操作將會看到 T1 中原子存儲(store)操作之前的所有的寫內(nèi)存操作(帶來的結(jié)果)
release-consume ordering
釋放-消費(fèi)順序,指定std::memory_order_consume內(nèi)存順序的原子載入(load)是消費(fèi)(consume)操作
當(dāng)兩個(gè)線程 T1、T2 滿足釋放-獲取順序時(shí),T2 中原子載入(load)操作完成后,T2 中對這個(gè)load操作有依賴的后續(xù)操作才將會看到 T1 中原子存儲(store)操作之前的所有的寫內(nèi)存操作(帶來的結(jié)果)
relaxed ordering
松散順序,std::memory_order_relaxed,以松散順序執(zhí)行的原子類型上的操作不參與synchronizes-with關(guān)系:
- 單線程中的同一個(gè)變量的操作仍然服從happens-before(sequence before)關(guān)系,但相對于其他線程的順序幾乎沒有任何要求
- 不同變量的松散操作可以被自由地重排
參考
《C++ Concurrency IN ACTION》
Memory model
std::memory_order
The as-if rule
Is the explanation of relaxed ordering erroneous in cppreference?
Does sequenced-before relation in C++11 prevent compiler/CPU reordering?
How to determine what is 'sequenced before' others?
浙公網(wǎng)安備 33010602011771號