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

Gil*_*esz 6 c++ x86 multithreading c++11

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

在29.幻灯片上的https://www.think-cell.com/en/career/talks/pdf/think-cell_talk_memorymodel.pdf上写

C++内存模型可确保顺序一致性

但是,在我以前的帖子中,我了解到C++内存具有弱内存模型 - 编译器可以根据需要进行重新排序 - 他必须满足规则那样满足.

Jon*_*ely 8

如果使用具有适当内存顺序的原子操作来保证顺序一致性, C++内存模型可确保顺序一致性.如果您只使用普通的非原子操作,或放松的原子操作,而不使用互斥锁,则无法保证顺序一致性.

如果无法观察到行为上的差异,那么编译器可以自由地重新排序操作,这就是as-if规则.因此,例如,如果重新排序顺序一致的原子会产生不同的可观察结果,那么它就不符合as-if规则.如果它不会产生不同的可观察结果,则允许重新排序.

  • 好的,很清楚.C++有弱模型. (2认同)

Pet*_*des 6

我想我通过阅读之前的幻灯片弄清楚了这张幻灯片在说什么:

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

  1. 所有线程的操作都按某种顺序执行
  2. 每个线程的操作按照它们的程序指定的顺序出现在这个序列中

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

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

因此,在第 29 张幻灯片上,作者说,一旦您使用 避免了数据竞争 UB std::atomic,程序就会运行,就好像一切都按程序顺序发生一样。 (如果您的所有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 上的原子性

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