是什么保证弱松弛的无竞争 CAS 循环终止?
What guarantees that a weak relaxed uncontended CAS loop terminates?
cppreference's page on compare_exchange 给出了以下示例代码(释义片段):
while(!head.compare_exchange_weak(new_node->next,
new_node,
std::memory_order_release,
std::memory_order_relaxed))
; // empty body
假设您 运行 这一次在线程 A 上,一次在线程 B 上。没有其他内容触及 head
或其相关数据。线程 B 的调用恰好在线程 A 发生后开始(实时),但 A 的更改尚未传播到 CPU 运行 线程 B 的缓存。
是什么迫使 A 对 B 进行更改?也就是说,为什么 B 的弱比较交换只是无限期地失败并且 CPU 缓存仍然陈旧的执行是不允许的?还是允许的?
似乎 CPU 运行ning B 没有被强制出去并同步 A 所做的更改,因为失败内存排序放宽了。那么为什么硬件会这样做呢?这是 C++ 规范或硬件的隐含保证,还是有界陈旧内存是标准的记录保证?
好问题!这实际上由 C++11 标准的 §1.10 中的第 25 条专门解决:
An implementation should ensure that the last value (in modification order) assigned by an atomic or
synchronization operation will become visible to all other threads in a finite period of time.
所以答案是肯定的,该值保证最终传播到另一个线程,即使在宽松的内存排序下也是如此。
cppreference's page on compare_exchange 给出了以下示例代码(释义片段):
while(!head.compare_exchange_weak(new_node->next,
new_node,
std::memory_order_release,
std::memory_order_relaxed))
; // empty body
假设您 运行 这一次在线程 A 上,一次在线程 B 上。没有其他内容触及 head
或其相关数据。线程 B 的调用恰好在线程 A 发生后开始(实时),但 A 的更改尚未传播到 CPU 运行 线程 B 的缓存。
是什么迫使 A 对 B 进行更改?也就是说,为什么 B 的弱比较交换只是无限期地失败并且 CPU 缓存仍然陈旧的执行是不允许的?还是允许的?
似乎 CPU 运行ning B 没有被强制出去并同步 A 所做的更改,因为失败内存排序放宽了。那么为什么硬件会这样做呢?这是 C++ 规范或硬件的隐含保证,还是有界陈旧内存是标准的记录保证?
好问题!这实际上由 C++11 标准的 §1.10 中的第 25 条专门解决:
An implementation should ensure that the last value (in modification order) assigned by an atomic or synchronization operation will become visible to all other threads in a finite period of time.
所以答案是肯定的,该值保证最终传播到另一个线程,即使在宽松的内存排序下也是如此。