seq_cst是否严格强于或等效于acq_rel?能否安全升级acq_rel为seq_cst?
关于C++原子内存序的两个疑问解答
首先明确你提到的“严格强于或等效于”定义:将任何memory_order_acq_rel操作替换为memory_order_seq_cst,都不会丢失acq_rel原本提供的任何语义保证——这个定义是准确的,下面基于此解答你的问题。
1)seq_cst是否和acq_rel一样是内存屏障?
是,但seq_cst的屏障特性不仅覆盖了acq_rel,还多了全局层面的核心约束。
你产生困惑的原因是两者线程内重排序规则的描述角度不同:
memory_order_acq_rel的核心是双向线程内屏障:当前线程中,所有内存读写操作既不能被重排到该操作的加载部分之前,也不能被重排到它的存储部分之后,普通内存操作和其他原子操作都受此约束。memory_order_seq_cst的线程内规则是:同一线程内的seq_cst原子操作之间不能重排序,但seq_cst操作可与非seq_cst的原子操作、普通内存操作做有限度重排序(比如单个seq_cst load的线程内约束和acquire load一致,单个seq_cst store和release store一致,seq_cst的读改写操作则和acq_rel一样是双向屏障)。但seq_cst额外提供了全局总序:所有线程看到的所有seq_cst操作的执行顺序完全一致,这是acq_rel完全不具备的关键强保证。
简言之,seq_cst包含了acq_rel的所有屏障能力,还额外增加了全局统一顺序的约束,它的内存屏障特性是强于acq_rel的。
2)能否安全地将任意acq_rel升级为seq_cst?
完全可以,且绝对安全。
memory_order_seq_cst的语义严格强于memory_order_acq_rel:acq_rel能保证的线程间可见性、线程内重排序约束,seq_cst全部满足,甚至还多了全局总序的保证。将acq_rel替换为seq_cst,只会让代码的内存一致性保证更强,绝不会破坏原有正确性——唯一可能的代价是性能略有下降(因为全局总序需要硬件层面的强同步,比如x86上的mfence指令),但安全性完全没问题。
内容的提问来源于stack exchange,提问作者TSK
相关产品推荐
相关产品推荐

