【问题标题】:How does CPU provides what memory_order_acquire guarantees?CPU 如何提供 memory_order_acquire 保证?
【发布时间】:2018-08-16 00:30:13
【问题描述】:

我一直在研究 C++ 11 中的内存顺序语义,但在理解 memory_order_acquire 在 CPU 级别如何工作时遇到了一些困难。

根据cppreference;

具有此内存顺序的加载操作执行获取操作 在受影响的内存位置上:当前没有读取或写入 线程可以在此加载之前重新排序。其他线程中的所有写入 释放相同的原子变量在当前可见 线程(请参阅下面的 Release-Acquire 顺序)

我真的无法理解的部分是;

当前线程中的任何读取或写入都不能在此之前重新排序 加载。

如果 CPU 在到达 'memory_order_acquire' 部分之前已经对命令进行了重新排序,会发生什么? CPU 是否恢复所有已完成的工作?这如何保证?

谢谢。

【问题讨论】:

  • 我认为您可能误解了该行。这意味着以后的读/写不能重新排序,以便它们在此加载之前发生。并不是说早期的读/写不能相对于彼此重新排序

标签: c++ multithreading c++11 cpu memory-barriers


【解决方案1】:

CPU 不会“到达”memory_order_acquire 部分。这些是编译器的指令。编译器必须使用其对 CPU 内存模型的了解来翻译它。

例如,如果 CPU 最多只能重新排序 2 条指令,则插入 2 条 NOP 指令将是实现这部分语义的一种相当简单的方法。

【讨论】:

    【解决方案2】:

    如第二段所述here

    程序的指令可能不会按照正确的顺序运行,只要最终结果是正确的。

    OoOE 不只是盲目地执行任何可用的东西。 CPU 将包含明确禁止跨边界重新排序这些访问的逻辑。正如那篇文章的其他地方所指出的,OoOE 的硅成本非常昂贵,很可能是由于这类问题。

    正如this SO question 中所述,内存屏障确实是有代价的——根据上述情况,这很有意义。基本上它们确实会导致正常的 OoOE 管道受到影响。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-10
      • 2017-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-13
      • 1970-01-01
      相关资源
      最近更新 更多