我一直在研究C ++ 11中的内存顺序语义,并且在理解memory_order_acquire如何在CPU级别工作方面有些困难。
根据cppreference;
具有此存储顺序的装入操作执行获取操作 在受影响的内存位置上:当前无读写 线程可以在此加载之前重新排序。所有写在其他线程中 释放相同原子变量的变量在当前可见 线程(请参见下面的“发布-获取”排序)
我真正无法理解的部分是;
在此之前,无法对当前线程中的任何读写进行重新排序 加载。
如果CPU在到达“ memory_order_acquire”部分之前就已经对命令进行了排序,该怎么办? CPU是否还原所有已完成的工作?如何保证呢?
谢谢。
答案 0 :(得分:1)
CPU不能“到达” memory_order_acquire
部分。这些是针对编译器的指令。编译器必须使用对CPU内存模型的了解来翻译。
例如,如果CPU最多只能对2条指令进行重新排序,则插入2条NOP指令将是实现语义部分的一种相当简单的方法。
答案 1 :(得分:0)
第二段here
只要最终结果正确,程序的指令就可能无法以正确的顺序运行。
OoOE不仅盲目执行任何可用的操作。 CPU将包含明确禁止跨边界重新排序这些访问的逻辑。如该文章的其他部分所述,由于这种问题,OoOE的硅成本非常昂贵。
如this SO question中所述,内存屏障确实要付出代价-鉴于上述情况,这很有意义。基本上,它们确实会导致普通的OoOE管道遭受打击。