提问者:小点点

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


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

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

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

但是,在我的历史发文中,我了解到C内存具有弱内存模型编译器可以根据需要进行重新排序,他必须满足仿佛规则。


共3个答案

匿名用户

如果您使用具有适当内存顺序的原子操作来保证顺序一致性,则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时,这意味着非原子访问可以正常工作,而原子

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

这个“CPU是如何做到的?”问题更适合作为你后面问题的一部分:x86上的原子性

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

匿名用户

为具有未定义行为的语言定义语义学的唯一可能方法是描述顺序执行。因此,所有程序的行为都与顺序执行相同,或者没有程序定义了行为。

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