Will two relaxed writes to the same location in different threads always be seen in the same order by other threads?(其他线程是否总是以相同的顺序看到不同线程中对同一位置的两次轻松写入?)
问题描述
在 x86 架构上,存储到同一内存位置具有总顺序,例如,请参见此视频.C++11 内存模型有哪些保证?
On the x86 architecture, stores to the same memory location have a total order, e.g., see this video. What are the guarantees in the C++11 memory model?
更准确地说,在
-- Initially --
std::atomic<int> x{0};
-- Thread 1 --
x.store(1, std::memory_order_release);
-- Thread 2 --
x.store(2, std::memory_order_release);
-- Thread 3 --
int r1 = x.load(std::memory_order_acquire);
int r2 = x.load(std::memory_order_acquire);
-- Thread 4 --
int r3 = x.load(std::memory_order_acquire);
int r4 = x.load(std::memory_order_acquire);
结果 r1==1, r2==2, r3==2, r4==1
是否被允许(在 x86 以外的某些架构上)?如果我用 std::memory_order_relaxed
替换所有 memory_order
会怎样?
would the outcome r1==1, r2==2, r3==2, r4==1
be allowed (on some architecture other than x86)? What if I were to replace all memory_order
's by std::memory_order_relaxed
?
推荐答案
不,这样的结果是不允许的.§1.10 [intro.multithread]/p8, 18(引用 N3936/C++14;在 N3337/C++11 的第 6 和 16 段中找到相同的文本):
No, such an outcome is not allowed. §1.10 [intro.multithread]/p8, 18 (quoting N3936/C++14; the same text is found in paragraphs 6 and 16 for N3337/C++11):
8 对特定原子对象 M 的所有修改都发生在某些特定的总顺序,称为 M 的修改顺序.
8 All modifications to a particular atomic object M occur in some particular total order, called the modification order of M.
18 如果原子对象 M 的值计算 A 发生在 a 之前M 的值计算 B,A 从副作用 X 中取值在 M 上,那么 B 计算的值要么是存储的值X 或由副作用 Y 存储在 M 上的值,其中 Y 在 X 之后M 的修改顺序. [注意:这个要求被称为读读连贯.—尾注 ]
18 If a value computation A of an atomic object M happens before a value computation B of M, and A takes its value from a side effect X on M, then the value computed by B shall either be the value stored by X or the value stored by a side effect Y on M, where Y follows X in the modification order of M. [ Note: This requirement is known as read-read coherence. —end note ]
在您的代码中有两个副作用,到了 p8,它们以某种特定的总顺序出现.在线程 3 中,计算要存储在 r1
中的值的值计算发生在 r2
之前,因此给定 r1 == 1
和r2 == 2
我们知道,按照x
的修改顺序,线程1执行的存储先于线程2执行的存储.在这种情况下,Thread 4
无法在不与 p18 冲突的情况下观察 r3 == 2, r4 == 1
.这与使用的 memory_order
无关.
In your code there are two side effects, and by p8 they occur in some particular total order. In Thread 3, the value computation to calculate the value to be stored in r1
happens before that of r2
, so given r1 == 1
and r2 == 2
we know that the store performed by Thread 1 precedes the store performed by Thread 2 in the modification order of x
. That being the case, Thread 4
cannot observe r3 == 2, r4 == 1
without running afoul of p18. This is regardless of the memory_order
used.
p21(N3337 中的 p19)中有一个相关的注释:
There is a note in p21 (p19 in N3337) that is relevant:
[ 注意:有效的上述四个连贯性要求禁止编译器将原子操作重新排序为单个对象,即使这两个操作都是松弛的负载.这有效地使大多数 C++ 可用硬件提供的缓存一致性保证原子操作.—尾注 ]
[ Note: The four preceding coherence requirements effectively disallow compiler reordering of atomic operations to a single object, even if both operations are relaxed loads. This effectively makes the cache coherence guarantee provided by most hardware available to C++ atomic operations. —end note ]
这篇关于其他线程是否总是以相同的顺序看到不同线程中对同一位置的两次轻松写入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:其他线程是否总是以相同的顺序看到不同线程中对同一位置的两次轻松写入?
基础教程推荐
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 使用从字符串中提取的参数调用函数 2022-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 从 std::cin 读取密码 2021-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01