我正在阅读有关 C++ 中的内存顺序的内容。我可以很好地理解放松和获取-释放模型。但我正在努力解决顺序一致性问题。
如果我没记错的话,从参考参数 https://en.cppreference.com/w/cpp/atomic/memory_order#:%7E:text=same%20atomic%20variable.-,memory_order_seq_cst,-A%20load%20operation, std::memory_order_seq_cst
“操作”相当于:
- 当操作为“加载”时,获取操作加上单个总订单。
- 当操作为“存储”时,释放操作加上单个总订单。
- 当操作为“读-修改-写”时,acq-rel 操作加上单个全序。
但到底是什么情况std::memory_order_seq_cst
'栅栏'?它相当于其中的哪一个?
- 获取栅栏加上单个总订单。
- 释放栅栏加上单个总订单。
- 一个 acq-rel 围栏加上一个总订单。
如果和上面其中之一是等价的,那另外两个呢?
据我所知,如果是情况 1(获取栅栏),编译器可以自由地将任何写操作从栅栏上方移动到栅栏下方。类似地,如果是情况 2(释放栅栏),编译器可以自由地将任何读取操作从栅栏下方移动到栅栏上方。最后,如果是情况 3(acq-rel 栅栏),则不允许编译器跨栅栏移动任何指令。它是否正确?
我仍然很困惑。以上说法可能不正确。有不对的地方请指正。
简而言之,就是情况3。
A seq_cst
栅栏包括栅栏的所有功能acq_rel
栅栏。参见 [atomics.fences p5.5]:
是一个顺序一致的获取和释放栅栏,如果order == memory_order::seq_cst
.
因此,它特别是一个获取和释放栅栏。而且它也是一个顺序一致的栅栏,这意味着它以与那里规定的规则一致的方式包含在[atomics.order p4]中定义的总顺序S中。
正式的C++内存模型没有“重新排序”的概念。然而,你是对的,一个典型的实现seq_cst
栅栏可以防止货物和物资在任一方向上重新排序。请注意,这严格强于acq_rel
栅栏,这将允许栅栏之前的存储与栅栏之后的负载一起重新排序(StoreLoad 重新排序)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)