我有一些与C 11中的内存模型有关的问题。
在29https://www.think-cell.com/en/career/talks/pdf/think-cell_talk_memorymodel.pdf。幻灯片是写的
C内存模型保证顺序一致性
但是,在我的历史发文中,我了解到C内存具有弱内存模型编译器可以根据需要进行重新排序,他必须满足仿佛规则。
如果您使用具有适当内存顺序的原子操作来保证顺序一致性,则C内存模型可以保证顺序一致性。如果您只使用普通的非原子操作,或松弛的原子,并且没有互斥体,则无法保证顺序一致性。
如果无法观察到行为的差异,编译器可以自由地重新排序操作,这是假设规则。例如,如果重新排序顺序一致的原子会产生不同的可观察结果,那么它不符合假设规则。如果它不会产生不同的可观察结果,那么允许重新排序。
我想我通过阅读早期的幻灯片,明白了那张幻灯片在说什么:
幻灯片12:顺序一致性[Leslie Lamport,1979]
任何执行的结果都是相同的
幻灯片14:无数据竞争程序的顺序一致性
SC-DRF:
所以在幻灯片29上,作者说一旦你使用std::atomic
避免数据竞争UB,程序就会像一切都按程序顺序发生一样运行。(如果你所有的std::atomic
操作都使用默认的memory_order_seq_cst
)。
这是查看C的弱(对于非原子对象)内存模型的一种有趣方式。这看起来像一组很好的幻灯片。SC原子操作是强有序的,并且有点像非原子操作的单向屏障。(如果有的话,对于放松的原子操作)。
请注意,无数据竞争意味着您不能在任意时间查看非原子变量,只有当您确定没有其他线程正在写入它们时。(通常通过与获取负载的同步关系,看到编写者完成的释放存储或互斥锁。)无数据竞争部分是这里的关键;如果你不小心,很容易出现数据竞争UB。当编译为真实CPU的asm时,这意味着非原子访问可以正常工作,而原子
第二部分:请不要养成同时问两个截然不同的问题的习惯。
这个“CPU是如何做到的?”问题更适合作为你后面问题的一部分:x86上的原子性
我已经写好了大部分答案,我会放在那里。
为具有未定义行为的语言定义语义学的唯一可能方法是描述顺序执行。因此,所有程序的行为都与顺序执行相同,或者没有程序定义了行为。
你在C/C中同时拥有两者的想法是一个骗局。程序必须按顺序运行才能使语义学有意义。