CPU 如何提供 memory_order_acquire 的保证?
How does CPU provides what memory_order_acquire guarantees?
我一直在研究 C++ 11 中的内存顺序语义,但在理解 memory_order_acquire 如何在 CPU 级别工作时遇到了一些困难。
根据cppreference;
A load operation with this memory order performs the acquire operation
on the affected memory location: no reads or writes in the current
thread can be reordered before this load. All writes in other threads
that release the same atomic variable are visible in the current
thread (see Release-Acquire ordering below)
我真正无法理解的部分是;
no reads or writes in the current thread can be reordered before this
load.
如果 CPU 在到达 'memory_order_acquire' 部分之前已经对命令重新排序,会发生什么情况? CPU 是否还原所有已完成的工作?这怎么能保证?
谢谢。
如第二段所述here
The instructions of the program may not be run in the correct order, as long as the end result is correct.
OoOE 不只是盲目地执行任何可用的东西。 CPU 将包含明确禁止跨边界重新排序这些访问的逻辑。正如该文章其他地方所指出的,OoOE 的硅成本非常昂贵,很可能是由于此类问题。
如 this SO question 中所述,内存障碍确实会带来成本 - 鉴于上述情况,这很有意义。基本上它们确实会导致正常的 OoOE 管道受到冲击。
CPU 没有 "reach" memory_order_acquire
部分。这些是编译器的说明。编译器必须使用它对 CPU 内存模型的了解来翻译它。
例如,如果 CPU 只会对最多 2 条指令进行重新排序,插入 2 条 NOP 指令将是实现这部分语义的一种相当简单的方法。
我一直在研究 C++ 11 中的内存顺序语义,但在理解 memory_order_acquire 如何在 CPU 级别工作时遇到了一些困难。
根据cppreference;
A load operation with this memory order performs the acquire operation on the affected memory location: no reads or writes in the current thread can be reordered before this load. All writes in other threads that release the same atomic variable are visible in the current thread (see Release-Acquire ordering below)
我真正无法理解的部分是;
no reads or writes in the current thread can be reordered before this load.
如果 CPU 在到达 'memory_order_acquire' 部分之前已经对命令重新排序,会发生什么情况? CPU 是否还原所有已完成的工作?这怎么能保证?
谢谢。
如第二段所述here
The instructions of the program may not be run in the correct order, as long as the end result is correct.
OoOE 不只是盲目地执行任何可用的东西。 CPU 将包含明确禁止跨边界重新排序这些访问的逻辑。正如该文章其他地方所指出的,OoOE 的硅成本非常昂贵,很可能是由于此类问题。
如 this SO question 中所述,内存障碍确实会带来成本 - 鉴于上述情况,这很有意义。基本上它们确实会导致正常的 OoOE 管道受到冲击。
CPU 没有 "reach" memory_order_acquire
部分。这些是编译器的说明。编译器必须使用它对 CPU 内存模型的了解来翻译它。
例如,如果 CPU 只会对最多 2 条指令进行重新排序,插入 2 条 NOP 指令将是实现这部分语义的一种相当简单的方法。