gpt4 book ai didi

c++ - 发布顺序的概念在实践中有用吗?

转载 作者:太空狗 更新时间:2023-10-29 22:54:25 24 4
gpt4 key购买 nike

C++ 原子语义仅保证由执行释放写入(简单或读取-修改-写入)操作的最后一个线程执行的内存操作的可见性(通过先发生关系)。

考虑

int x, y;
atomic<int> a;

线程 1:

x = 1;
a.store(1,memory_order_release);

线程 2:

y = 2;
if (a.load(memory_order_relaxed) == 1))
a.store(2,memory_order_release);

那么 a == 2 的观察意味着线程 2 操作的可见性 (y == 2) 而不是线程 1(甚至无法读取 x )。

据我所知,多线程的实际实现使用栅栏概念(有时还使用释放存储),但不使用高级 C++ 概念发生前或释放序列;我看不出这些概念映射到了哪些真实的硬件细节。

a 中的 2 的值全局可见时,真正的实现如何不保证线程 1 内存操作的可见性?

也就是说,release-sequence的定义有什么好处吗?为什么发布顺序不会扩展到修改顺序中的每个后续修改?

特别考虑傻线程 3:

if (a.load(memory_order_relaxed) == 2))
a.store(2,memory_order_relaxed);

silly-thread 3 能否在任何真实硬件上抑制任何可见性保证?换句话说,如果值 2 是全局可见的,如何使其再次全局可见会破坏任何排序?

我对真实多处理的心智模型不正确吗?部分可见的值可以在某些 CPU 上但注意到另一个吗?

(当然,我假设一个非疯狂的语义用于轻松的写入,因为回到过去的写入使 C++ 的语言语义绝对荒谬,不像 Java 这样的安全语言总是具有有限的语义。没有真正的实现可以有疯狂的,非-因果放松语义。)

最佳答案

让我们先回答你的问题:

Why wouldn't the release-sequence extend to every subsequent modification in the modification order?

因为如果是这样,我们将失去一些潜在的优化。例如,考虑线程:

x = 1;                            // #1
a.store(1,memory_order_relaxed); // #2

根据当前规则,编译器能够重新排序#1 和#2。然而,在释放序列的扩展之后,编译器不允许对这两行重新排序,因为另一个线程像你的线程 2 可能会引入一个以#2 为首的释放序列,并以一个释放操作结尾,因此有可能有些读- 另一个线程中的获取操作将与#2 同步。


您举了一个具体的例子,并声称所有的实现都会产生一个特定的结果,而语言规则并不能保证这个结果。这不是问题,因为语言规则旨在处理所有情况,而不仅仅是您的具体示例。当然可以改进语言规则,以便它可以保证您的特定示例的预期结果,但这不是一项微不足道的工作。至少,正如我们上面所说,简单地扩展发布顺序的定义并不是一个可以接受的解决方案。

关于c++ - 发布顺序的概念在实践中有用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56031747/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com