内存排序中原子读-修改-写(RMW)操作的处理
回答有关原子读性质的问题-修改-写入(RMW)操作,C 标准将它们分类为具有组合获取和释放语义的单个操作
排序的含义
此指定意味着在 RMW 操作之前或之后,同一线程中发生的内存读取或写入不能重新排序。但是,它并不排除 RMW 的内部读写组件之间重新排序的可能性。
具体示例
考虑提供的代码示例:
std::atomic<int> x, y; void thread_A() { x.exchange(1, std::memory_order_acq_rel); y.store(1, std::memory_order_relaxed); } void thread_B() { int yy = y.load(std::memory_order_acquire); int xx = x.load(std::memory_order_acquire); std::cout << xx << ", " << yy << std::endl; }
在这种情况下,线程 B 确实可以输出 0, 1。这是因为在线程 A 的 RMW 操作可以在内部重新排序,从而允许线程 B 观察加载 (0) 之后但存储 (1) 之前的状态。
ARM64 实现
RMW 操作的 ARM64 实现(如 ldaxr、stlxr 和 str 指令所述)符合标准的期望。 str 指令可以在 stlxr 指令之前可见,可能会导致线程 B 观察到 0、1。
内存顺序影响
将 memory_order_acq_rel 替换为 seq_cst 将不影响此行为,因为它仅引入相对于其他 seq_cst 操作的附加语义,这些语义是代码示例中不存在。
结论
C 中的原子 RMW 操作是具有获取-释放语义的单一操作。虽然它们防止外部操作前后重新排序,但其内部组件之间重新排序的可能性允许出现类似代码示例中的场景,其中线程 B 可以输出 0、1。
以上是C 原子读-修改-写操作中的内部重新排序如何影响内存排序?的详细内容。更多信息请关注PHP中文网其他相关文章!