X86 上,load(memory_order_seq_cst) 或atomic_fetch_add(0, memory_order_relaxed) 哪一个性能更好?

问题描述 投票:0回答:1

问题1:我有一个主要用于计数的变量,只关心它自己的值。以下两种方法哪一种性能更好?

方法一: 读取:aaa.atomic_fetch_add(0, memory_order_relaxed) 写入:aaa.atomic_fetch_add(1, memory_order_relaxed)

方法2: 读取:aaa.load(memory_order_seq_cst) 写入:aaa.atomic_fetch_add(1, memory_order_seq_cst)

问题2:如果线程T1:aaa可能已经存在于T1的storebuffer中,T1的原子RMW操作会刷新storebuffer吗?

c++ x86 x86-64 stdatomic
1个回答
0
投票

在 x86 上,

seq_cst
加载不需要额外的障碍,因此与
relaxed
加载一样便宜,除了编译时重新排序之外。纯负载比任何 RMW 都要快得多,例如在无争用情况下,每个时钟 3 个时钟与每 20 个时钟 1 个时钟,并且纯负载可通过多个并行读取器进行扩展。 (https://uops.info/ 看看
lock xadd
mov r32, mem

原子 RMW 是 x86 上的全面障碍;在 asm 中,没有办法让它们比

seq_cst
更弱。 (所以是的,他们必须等待存储缓冲区耗尽。)只有
.store(val, seq_cst)
需要任何额外的屏障指令(通常是
lock add byte [rsp], 0
,因为在许多 CPU 上它比
mfence
更快。)

就线程间延迟而言,两者应该表现相同; 存储缓冲区已经尝试尽快耗尽自身以避免变满和停滞。 (当从前端向后端发出存储 uop 时,前端必须分配一个存储缓冲区条目,因此不这样做对于乱序 exec 能看到的距离来说会更糟。)请参阅除了提供必要的保证之外,硬件内存屏障是否还能使原子操作的可见性更快?(否)

© www.soinside.com 2019 - 2024. All rights reserved.