【问题标题】:Are memory barriers needed because of cpu out of order execution or because of cache consistency problem?由于 cpu 无序执行或缓存一致性问题,是否需要内存屏障?
【发布时间】:2021-01-06 06:07:34
【问题描述】:

我想知道为什么需要内存屏障,我已经阅读了一些关于这个主题的文章。
有人说是因为 cpu 乱序执行,而others 说是因为缓存一致性问题导致存储缓冲区和队列无效。
那么,需要内存屏障的真正原因是什么? cpu乱序执行还是缓存一致性问题?或两者? cpu乱序执行和缓存一致性有关系吗? x86和arm有什么区别?

【问题讨论】:

  • 这两者都没有具体关系。它们基本上会停止新事务并允许正在运行的事务完成以避免可能导致在特定系统设计中发生不希望/可预测的事情的竞争条件。允许您对处于已知状态的系统执行特定事务。
  • 所有并行的事情都在正常进行,它基本上是受控的混乱,这将暂停混乱。就像停止交通以帮助一个缓慢/老人过马路,然后混乱可以继续。
  • 一些系统会有单独的指令屏障和数据屏障来处理或隔离不同的区域。您需要它们的地方非常特定于系统,这并不意味着 x86 this 和 arm that 或缓存 this 和 pipeline that,但是这个特定的 x86 处理器,以这种方式实现的这个特定的 arm 核心在执行此操作之前需要一个屏障。并不是所有的 x86 处理器或 arm 内核都需要它在那个地方进行操作。它们用于防止潜在的竞争条件导致不良或不可预测的结果。

标签: x86 arm cpu-architecture cpu-cache memory-barriers


【解决方案1】:

当 ISA 的内存排序规则弱于您的算法所需的语义时,您需要设置障碍来排序此核心/线程对全局可见的一致缓存的访问。

缓存总是一致,但这与一致性(多个操作之间的排序)是分开的。

您可以在有序 CPU 上进行内存重新排序。更详细地,How is load->store reordering possible with in-order commit? 展示了如何在管道上进行内存重新排序,该管道开始按程序顺序执行指令,但缓存允许未命中命中和/或存储缓冲区允许OoO 提交。

相关:


有关更多基本信息,另请参阅 https://preshing.com/20120710/memory-barriers-are-like-source-control-operations/https://preshing.com/20120930/weak-vs-strong-memory-models。 x86 有一个“强”的内存排序模型:程序顺序加上一个带有存储转发的存储缓冲区。 C++ acquirerelease 是“免费的”,只有原子 RMW 和 seq_cst 存储需要屏障。

ARM 有一个“弱”的内存排序模型:只有 C++ memory_order_consume(数据依赖排序)是“免费的”,获取和释放需要特殊指令(如 ldar/stlr)或屏障。

【讨论】:

  • @cong:如果它仍然有一个存储缓冲区,那么是的,你需要一个 mfence 屏障(或锁定指令)来实现顺序一致性。 NT 商店大多毫无意义,所以sfence 可能没有用处。大多数代码不需要那个,acq_rel 很好。只有像双重检查锁定这样的东西才重要。正如我所说的那样,缓存与需要内存屏障无关。
  • @cong:嗯,我想对于没有存储缓冲区的 x86 CPU 来说,在以后加载之后仍然可以允许无序 执行 存储。像这样的 CPU 是完全不切实际的。存储缓冲区是获得大量性能的廉价方法。在允许任何内存重新排序的内存模型中,如果不将 exec 与缓存/内存解耦,OoO exec 将是一种巨大的资源浪费。成为 x86 意味着 OoO exec 受到强大的内存排序规则的限制,没有存储缓冲区来将 exec 与可见性分离。在现实生活中,即使是简单的有序 CPU 也有存储缓冲区。
  • @cong:此外,这样的 CPU 必须证明在执行存储之前没有任何干预指令可能出错。一旦一家商店成为全球可见的,如果您发现错误推测,您将无法“收回”。做 OoO exec 的正常方式是行不通的;它依赖于存储缓冲区来保持非退休(推测)存储私有,直到确定之前没有指令出错。 (即当存储指令从 ROB 中退出时,存储缓冲区条目“毕业”并有资格提交到 L1d 缓存。在退出之前,所有内容都被视为推测性的)
  • AMD 甚至显然有一个推测性的退休后存储缓冲区,即使在退休后(但在可见性之前)也允许回滚以支持快速原子。
  • @cong: agner.org/optimizeblog.stuffedcow.net/2013/05/measuring-rob-capacityrealworldtech.com/sandy-bridge 之类的文章(以及 RWT 论坛),有时英特尔的优化手册虽然有点乱。此外,一些性能计数器事件(及其名称/描述)的存在给出了提示:Linux 上的perf list,或oprofile.sourceforge.io/docs/intel-sandybridge-events.php。鉴于这些 cpu 架构实现细节的来源,我们可以推断这些部分必须如何组合在一起才能实现遵循 x86 ISA 规则的 CPU。
猜你喜欢
  • 2017-08-02
  • 2015-09-06
  • 2014-09-03
  • 1970-01-01
  • 1970-01-01
  • 2012-09-08
  • 2011-10-12
  • 2020-03-18
  • 2017-07-31
相关资源
最近更新 更多