小编Alb*_*das的帖子

在程序员级别使用 C++ std::atomic 保证什么?

我已经听并阅读了几篇关于 的文章、演讲和 stackoverflow 问题std::atomic,我想确定我已经很好地理解了它。因为由于 MESI(或派生)缓存一致性协议、存储缓冲区、无效队列等可能存在延迟,我仍然对缓存行写入可见性感到困惑。

我读到 x86 具有更强的内存模型,如果缓存失效延迟,x86 可以恢复已启动的操作。但我现在只对作为 C++ 程序员应该假设的内容感兴趣,而与平台无关。

[T1:线程1 T2:线程2 V1:共享原子变量]

我知道 std::atomic 保证,

(1) 变量上不会发生数据竞争(由于对缓存行的独占访问)。

(2) 根据我们使用的 memory_order,它保证(使用屏障)顺序一致性发生(在屏障之前、屏障之后或两者兼而有之)。

(3) 在T1 上的原子写(V1) 之后,T2 上的原子RMW(V1) 将是一致的(它的缓存行将已用T1 上的写入值更新)。

但正如缓存一致性入门所提到的,

所有这些事情的含义是,默认情况下,加载可以获取陈旧数据(如果相应的失效请求位于失效队列中)

那么,以下说法正确吗?

(4)std::atomic不保证 T2 在 T1 上的原子写(V)之后不会在原子读(V)上读取“陈旧”值。

问题(4)是否正确:如果无论延迟如何,T1 上的原子写入都会使缓存行失效,那么为什么 T2 在执行原子 RMW 操作而不是原子读取时等待失效生效?

问题(4)是否错误:线程何时可以在执行中读取“过时”值并且“它是可见的”?

我非常感谢你的回答

更新 1

所以看来我在(3)上错了。想象以下交错,对于初始 V1=0:

T1: W(1)
T2:      R(0) M(++) W(1)
Run Code Online (Sandbox Code Playgroud)

即使在这种情况下 T2 的 RMW 保证完全发生在 W(1) 之后,它仍然可以读取“陈旧”值(我错了)。据此,atomic 不保证完全缓存一致性,只保证顺序一致性。

更新 2

(5) 现在想象这个例子(x = y = 0 并且是原子的):

T1: x …
Run Code Online (Sandbox Code Playgroud)

c++ concurrency caching atomic c++17

9
推荐指数
1
解决办法
436
查看次数

标签 统计

atomic ×1

c++ ×1

c++17 ×1

caching ×1

concurrency ×1