C++中的内存模型:顺序一致性和原子性

Memory Model in C++ : sequential consistency and atomicity

本文关键字:顺序 一致性 原子性 模型 内存 C++      更新时间:2023-10-16

我有一些与C++11中的内存模型有关的问题。

Onhttps://www.think-cell.com/en/career/talks/pdf/think-cell_talk_memorymodel.pdf29日。幻灯片已写入

C++内存模型保证的顺序一致性

但是,在我之前的帖子中,我了解到C++内存有弱内存模型——编译器可以根据自己的意愿进行重新排序——他必须满足,就好像规则一样。

如果使用具有适当内存顺序的原子操作来保证顺序一致性,则C++内存模型可保证顺序一致。。如果您只使用普通的非原子操作,或者宽松的原子,并且没有互斥,那么序列一致性就不能得到保证。

如果不能观察到行为上的差异,编译器可以自由地对操作重新排序,这就是假设规则。因此,例如,如果顺序一致的原子重新排序会产生不同的可观察结果,那么它就不符合假设规则。如果它不会产生不同的可观察结果,那么可以重新排序。

我想我从阅读前面的幻灯片中明白了那张幻灯片在说什么:

幻灯片12:序列一致性[Leslie Lamport,1979]
任何执行的结果都与相同

  1. 所有线程的操作都在某些线程中执行顺序
  2. 每个线程的操作都按此顺序出现按照程序指定的顺序

幻灯片14:无数据竞赛程序的顺序一致性
SC-DRF:

  • 我们注意我们的程序不包含数据竞赛
  • 系统保证顺序一致执行

因此,在第29张幻灯片上,作者说一旦您使用std::atomic避免了数据竞争UB,程序就会运行,就像一切都按程序顺序发生一样(如果所有std::atomic操作都使用默认的memory_order_seq_cst)。

这是一种有趣的方法来看待C++的弱(对于非原子对象)内存模型。这张幻灯片看起来不错SC原子操作是强有序的,有点像非原子操作的单向屏障(对于轻松的原子操作,如果有)。

请注意,无数据竞争意味着您不能在任意时间查看非原子变量,只有当您确定没有其他线程在编写这些变量时。(通常通过与获取负载的同步关系,看到由编写器或互斥体完成的释放存储。)无数据竞争部分是这里的关键;如果你不小心的话,很容易发生数据竞赛UB。当编译到真正CPU的asm时,这意味着非原子访问可以正常工作,而atomic<T> seq_cst访问需要阻止编译时间和运行时重新排序。https://preshing.com/20120625/memory-ordering-at-compile-time/


第二部分:请不要养成同时问两个截然不同的问题的习惯。

这个";CPU是怎么做到的"这个问题将更适合作为您稍后问题的一部分:x86 上的原子性

我已经写好了大部分答案,我会把它放在那里。

为具有未定义行为的语言定义语义的唯一可能方法是描述顺序执行。呃,所有程序的行为都像顺序执行一样,或者没有程序定义行为。

在C/C++中同时拥有这两者的想法是一个骗局程序必须按顺序运行才能使语义有意义