如何测试std::memory_order_relaxed的行为?
How to test the behavior of std::memory_order_relaxed?
我已经阅读了 std::memory_order_relaxed 的文档。
宽松排序的部分解释是....
// Thread 1:
r1 = y.load(memory_order_relaxed); // A
x.store(r1, memory_order_relaxed); // B
// Thread 2:
r2 = x.load(memory_order_relaxed); // C
y.store(42, memory_order_relaxed); // D
对此的解释是...
[It] is allowed to produce r1 == r2 == 42
. In particular, this may occur if D is completed before C in thread 2, either due to compiler reordering or at runtime.
我已经理解了解释,尝试在我的电脑上测试如下代码:
std::atomic<int> x = {0};
std::atomic<int> y = {0};
int r1, r2;
void task1() {
// Thread 1:
r1 = y.load(memory_order_relaxed); // A
x.store(r1, memory_order_relaxed); // B
}
void task2() {
// Thread 2:
r2 = x.load(memory_order_relaxed); // C
y.store(42, memory_order_relaxed); // D
}
int main()
{
std::thread t2 (task2);
std::thread t1 (task1);
t1.join();
t2.join();
cout << "r1: " << r1
<< "\nr2: " << r2 << endl;
return 0;
}
此代码的结果是 never r1 == r2 == 42
,据说这是该文档中的一种可能行为。
这段代码有没有错误?或者,有什么误会吗?
Or, is there any misunderstanding?
是的,有一个。 std::memory_order_relaxed
在您的程序中允许的是针对体系结构的实现(编译器),以生成可以观察到副作用的程序 r1 == r2 == 42
。
实现不必产生这样的程序,这样的程序也不必产生那种副作用;无论如何这是一个可能的结果。
How to test the behavior of std::memory_order_relaxed?
我看不到这个问题的通用解决方案。您只能检查 you 观察到的副作用是否与 std::memory_order_relaxed
.
的规范匹配
您的代码有点幼稚,因为当第二个线程启动时,第一个线程可能已经完成。线程需要 运行 这些代码真正并发。
要使 r1 == r2 == 42
为真,需要在存储 D
之后重新排序负载 C
,x86 不会在存储 [=23= 之后重新排序负载 ] 目前,这样您可能永远不会在该平台上观察到这种重新排序(除非编译器将 C
重新排序为 D
)。
另一方面,ARM 和 PowerPC 的内存模型较弱。请参阅 运行时内存排序
table.
我已经阅读了 std::memory_order_relaxed 的文档。
宽松排序的部分解释是....
// Thread 1: r1 = y.load(memory_order_relaxed); // A x.store(r1, memory_order_relaxed); // B // Thread 2: r2 = x.load(memory_order_relaxed); // C y.store(42, memory_order_relaxed); // D
对此的解释是...
[It] is allowed to produce
r1 == r2 == 42
. In particular, this may occur if D is completed before C in thread 2, either due to compiler reordering or at runtime.
我已经理解了解释,尝试在我的电脑上测试如下代码:
std::atomic<int> x = {0};
std::atomic<int> y = {0};
int r1, r2;
void task1() {
// Thread 1:
r1 = y.load(memory_order_relaxed); // A
x.store(r1, memory_order_relaxed); // B
}
void task2() {
// Thread 2:
r2 = x.load(memory_order_relaxed); // C
y.store(42, memory_order_relaxed); // D
}
int main()
{
std::thread t2 (task2);
std::thread t1 (task1);
t1.join();
t2.join();
cout << "r1: " << r1
<< "\nr2: " << r2 << endl;
return 0;
}
此代码的结果是 never r1 == r2 == 42
,据说这是该文档中的一种可能行为。
这段代码有没有错误?或者,有什么误会吗?
Or, is there any misunderstanding?
是的,有一个。 std::memory_order_relaxed
在您的程序中允许的是针对体系结构的实现(编译器),以生成可以观察到副作用的程序 r1 == r2 == 42
。
实现不必产生这样的程序,这样的程序也不必产生那种副作用;无论如何这是一个可能的结果。
How to test the behavior of std::memory_order_relaxed?
我看不到这个问题的通用解决方案。您只能检查 you 观察到的副作用是否与 std::memory_order_relaxed
.
您的代码有点幼稚,因为当第二个线程启动时,第一个线程可能已经完成。线程需要 运行 这些代码真正并发。
要使 r1 == r2 == 42
为真,需要在存储 D
之后重新排序负载 C
,x86 不会在存储 [=23= 之后重新排序负载 ] 目前,这样您可能永远不会在该平台上观察到这种重新排序(除非编译器将 C
重新排序为 D
)。
另一方面,ARM 和 PowerPC 的内存模型较弱。请参阅 运行时内存排序 table.