x86 - 由于 cpu 乱序执行或缓存一致性问题,是否需要内存屏障?
问题描述
我想知道为什么需要内存屏障,我已经阅读了一些关于这个主题的文章。
有人说是因为 cpu 乱序执行,也有人说是因为缓存一致性问题导致存储缓冲区和队列无效。
那么,需要内存屏障的真正原因是什么?cpu乱序执行还是缓存一致性问题?或两者?cpu乱序执行和缓存一致性有关系吗?x86和arm有什么区别?
解决方案
当 ISA 的内存排序规则弱于您的算法所需的语义时,您需要障碍来排序此核心/线程对全局可见的一致缓存的访问。
缓存始终是一致的,但这与一致性(多个操作之间的排序)是分开的。
您可以在有序 CPU 上进行内存重新排序。更详细地说,如何使用按顺序提交进行加载->存储重新排序?展示了如何在开始按程序顺序执行指令的管道上进行内存重新排序,但使用允许未命中命中的缓存和/或允许 OoO 提交的存储缓冲区。
有关的:
- x86 CPU 是否重新排序指令?讨论内存重新排序与乱序执行之间的区别。(以及 x86 的强排序内存模型是如何通过硬件轨道排序在激进的乱序执行之上实现的,存储缓冲区将存储执行从存储可见性解耦到其他线程/内核。)
- x86 内存排序:使用早期存储重新排序的负载与处理器内转发
- 全局不可见的加载指令
另请参阅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
)或屏障。
推荐阅读
- r - 通过迭代 for 循环创建单个图,将图拼凑在一起
- php - 为什么我在 PHPmailer 中出现签名错误:错误:02001002
- javascript - 部分重叠过渡动画
- flutter - Flutter - 检查是否出现 TextFormField 错误文本的小部件测试结果不一致
- python - 如何在 python/pandas 的 csv 文件中用前面的值填充后续的空值?
- python - 在 pygame 中从精灵表创建动画时遇到问题
- javascript - 从 web json 文件中,在 javascript 中的不同对象中仅将一种名称的值相加?
- windows - 如何使 Microsoft Windows 模拟器工作
- django - Django 测试失败
没有属性“对象”错误 - sql - 替换 SQL 表中的所有双引号