问题描述
我想知道为什么需要内存障碍,并且我已经阅读了有关该主题的一些文章。
有人说这是因为cpu乱序执行,而others说是因为缓存一致性问题存储了缓冲区并使队列无效。
那么,需要内存屏障的真正原因是什么? cpu乱序执行或缓存一致性问题?或两者? cpu乱序执行是否与缓存一致性有关? x86和arm有什么区别?
解决方法
当ISA的内存排序规则比您的算法所需的语义弱时,您需要设置障碍来排序此核心/线程对全局可见的一致性缓存的访问。
缓存始终是一致的,但这与一致性(多个操作之间的顺序)不同。
您可以在有序CPU上对内存进行重新排序。更详细地讲,How is load->store reordering possible with in-order commit?显示了如何在以程序顺序开始执行指令的管道上获得内存重新排序,并具有允许未命中和/或存储的高速缓存允许OoO提交的缓冲区。
相关:
- Does an x86 CPU reorder instructions?讨论了内存重新排序与exec失序之间的区别。 (以及如何通过硬件轨道排序在主动无序执行的基础上实现x86的强排序内存模型,并且商店缓冲区将商店 execution 与商店 visibility 脱钩到其他线程/核心。)
- x86 memory ordering: Loads Reordered with Earlier Stores vs. Intra-Processor Forwarding
- Globally Invisible load instructions
另请参阅https://preshing.com/20120710/memory-barriers-are-like-source-control-operations/和https://preshing.com/20120930/weak-vs-strong-memory-models了解更多基础知识。 x86具有“强”内存排序模型:程序顺序以及具有存储转发功能的存储缓冲区。 C ++ acquire
和release
是“免费的”,只有原子RMW和seq_cst存储需要障碍。
ARM有一个“弱”的内存排序模型:只有C ++ memory_order_consume
(数据相关性排序)是“免费的”,获取和发布都需要特殊的指令(例如ldar
/ stlr
)或障碍。