gpt4 book ai didi

c++ - std::atomic::fetch_add 是 x86-64 上的序列化操作吗?

转载 作者:太空狗 更新时间:2023-10-29 21:11:17 25 4
gpt4 key购买 nike

考虑以下代码:

std::atomic<int> counter;

/* otherStuff 1 */
counter.fetch_add(1, std::memory_order_relaxed);
/* otherStuff 2 */

x86-64(比如不到 5 年的旧架构)中是否有一条指令允许 otherStuff 1 和 2 在 fetch_add 中重新排序,或者它是否会一直序列化?

编辑:

这看起来像是总结为“lock add 是 x86 上的内存屏障吗?”似乎不是,尽管我不确定在哪里可以找到相关引用。

最佳答案

首先让我们看看编译器在使用 std::memory_order_relaxed 时允许做什么。
如果 otherStuff 1/2 和原子操作之间没有依赖关系,它当然可以重新排序语句。例如:

g = 3;
a.fetch_add(1, memory_order_relaxed);
g += 12;

clang++ 生成以下程序集:

lock   addl $0x1,0x2009f5(%rip)        # 0x601040 <a>
movl $0xf,0x2009e7(%rip) # 0x60103c <g>

这里 clang 冒昧地使用原子 fetch_add 操作重新排序 g = 3,这是一个合法的转换。

当使用 std::memory_order_seq_cst 时,编译器输出变为:

movl   $0x3,0x2009f2(%rip)        # 0x60103c <g>
lock addl $0x1,0x2009eb(%rip) # 0x601040 <a>
addl $0xc,0x2009e0(%rip) # 0x60103c <g>

语句的重新排序不会发生,因为不允许编译器这样做。读取-修改-写入 (RMW) 操作的顺序一致排序既是释放操作也是获取操作,因此,在编译器和 CPU 级别上不允许(可见的)语句重新排序。

你的问题是,在 X86-64 上,使用宽松排序的 std::atomic::fetch_add 是否是一个序列化操作..
答案是:是的,如果您不考虑编译器重新排序的话。

X86 架构上,RMW 操作总是刷新存储缓冲区,因此实际上是一种序列化和顺序一致的操作。

你可以说,在 X86 CPU 上,每个 RMW 操作:

  • 对于在它之前的内存操作是一个释放操作,对于在它之后的内存操作是一个获取操作。
  • 在所有线程观察到的单个总顺序中变得可见。

关于c++ - std::atomic::fetch_add 是 x86-64 上的序列化操作吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51086258/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com