如何测试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.