led*_*ter 5 c++ memory-model stdatomic c++20
我读过这个问答:与“(简单)发生在之前”相比,“强烈发生在之前”的意义是什么?
作者给出了一个有趣的评估的概述,该评估在 C++20 之前是不可能的,但显然从 C++20 开始是可能的:
.-- T3 y.store(3, seq_cst); --. (2)
| | | strongly
| | sequenced before | happens
| V | before
| T3 a = x.load(seq_cst); // a = 0 --. <-' (3)
| : coherence-
| : ordered
| : before
| T1 x.store(1, seq_cst); <-' --. --. (4)
| | |st |
| | sequenced before |h |
| V |b |
| . T1 y.store(1, release); <-' | (x)
| | : | strongly
| | : synchronizes with | happens
| | V | before
| > T2 b = y.fetch_add(1, seq_cst); // b = 1 --. | (1)
| | |st |
| | sequenced before |h |
| V |b |
'-> T2 c = y.load(relaxed); // c = 3 <-' <-'
Run Code Online (Sandbox Code Playgroud)
右侧的数字表示可能的seq_cst顺序(为了方便起见,我添加了 (x);该行不参与 SC 顺序,因为它不是 SC 操作)。
我试图了解y这个例子中的修改顺序是什么,但我不知道如何确定它。y(或者这个评估有多种可能的修改顺序吗?..)
更一般地说,C++ 中原子变量的修改顺序是如何定义的?例如有这样的:https://en.cppreference.com/w/cpp/atomic/memory_order
写-写一致性:如果修改某个原子 M(写入)的评估 A 发生在修改 M 的评估 B 之前,则 A 在 M 的修改顺序中出现早于 B
所以看来修改顺序必须与写-写发生之前一致。
它是唯一定义修改顺序的东西吗?
在上面的例子中,AFAIU 在 (2) 和 (1) 之间没有发生之前;那么 的修改顺序中哪个是第一个y?
模阶是y(x 1 2) (对于此评估)?
我相信这也可能有助于推理seq_cst顺序......
对象的修改顺序是线程在紧密循环运行中旋转时看到的顺序while(1) { y.load(relaxed); },并且碰巧看到每个更改。(并不是说这是实际观察它的有用方法,但每个对象都有自己的修改顺序,所有线程始终可以达成一致,就像在真实的 CPU 上一样,由于需要 MESI 独占所有权才能将存储提交到 L1d 缓存。或者查看它早期通过 POWER CPU 上的 SMT 线程之间的私有存储转发。)
一些随机事实:
relaxedrelaxed。我认为这个评估显示了实际有效的顺序,因此 mod 顺序y只是从上到下读取操作按(2) (x) (1)该顺序存储的值。(因为它使用了足够的seq_cst操作,所有线程都可以就顺序达成一致,并表明其他一些事情最终会在store(x)之后对 release store 进行排序。)seq_cst(2)
这个 eval 命令表示该(2)store 确实在 store 之前变得可见(x),因此(x)store 替换了它。
在 之前尘埃落定y.fetch_add (1),否则它会同步(2)而不是(x)。
更正,显然他们表明 的 修改顺序是合法的,尽管(存储 3) 和最终(x) (1) (2)之间有不同风格的happens-before链。这样,该商店在 之后、之前对 T2 可见。(2)y.load()fetch_addload
| 归档时间: |
|
| 查看次数: |
453 次 |
| 最近记录: |