gpt4 book ai didi

c++ - x86_64 和 ARM 上的原子 CAS 操作是否始终使用 std::memory_order_seq_cst?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:29:40 25 4
gpt4 key购买 nike

作为Anthony Williams said :

some_atomic.load(std::memory_order_acquire) does just drop through to a simple load instruction, and some_atomic.store(std::memory_order_release) drops through to a simple store instruction.

众所周知,在 x86 上,操作 load()store() 内存屏障 memory_order_consume, memory_order_acquire, memory_order_release , memory_order_acq_rel 不需要处理器指令。

但是在 ARMv8 我们知道这里是 load()store() 的内存屏障: http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-1-of-2 http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-2-of-2

关于CPU的不同架构:http://g.oswego.edu/dl/jmm/cookbook.html

接下来,除了在 x86 上的 CAS 操作之外,这两行具有不同内存屏障的代码在反汇编代码中是相同的 (MSVS2012 x86_64):

    a.compare_exchange_weak(temp, 4, std::memory_order_seq_cst, std::memory_order_seq_cst);
000000013FE71A2D mov ebx,dword ptr [temp]
000000013FE71A31 mov eax,ebx
000000013FE71A33 mov ecx,4
000000013FE71A38 lock cmpxchg dword ptr [temp],ecx

a.compare_exchange_weak(temp, 5, std::memory_order_relaxed, std::memory_order_relaxed);
000000013FE71A4D mov ecx,5
000000013FE71A52 mov eax,ebx
000000013FE71A54 lock cmpxchg dword ptr [temp],ecx

GCC 4.8.1 x86_64 - GDB编译的反汇编代码:

a.compare_exchange_weak(temp, 4, std::memory_order_seq_cst, std::memory_order_seq_cst);
a.compare_exchange_weak(temp, 5, std::memory_order_relaxed, std::memory_order_relaxed);

0x4613b7 <+0x0027> mov 0x2c(%rsp),%eax
0x4613bb <+0x002b> mov $0x4,%edx
0x4613c0 <+0x0030> lock cmpxchg %edx,0x20(%rsp)
0x4613c6 <+0x0036> mov %eax,0x2c(%rsp)
0x4613ca <+0x003a> lock cmpxchg %edx,0x20(%rsp)

在 x86/x86_64 平台上用于任何原子 CAS 操作,例如这样的示例 atomic_val.compare_exchange_weak(temp, 1, std::memory_order_relaxed, std::memory_order_relaxed);排序 std::memory_order_seq_cst?

如果 x86 上的任何 CAS 操作始终以顺序一致性(std::memory_order_seq_cst)运行而不管障碍,那么在 ARMv8 上它是一样的吗?

问题: std::memory_order_relaxed 的顺序是否应该在 x86 或 ARM 上阻止 CAS 的内存总线?

答案:x86 上,任何 compare_exchange_weak() 操作与任何 std::memory_orders(甚至 std::memory_order_relaxed) 始终转换为 LOCK CMPXCHG with lock bus, to be really atomic , 和 XCHG - "the cmpxchg is just as expensive as the xchg instruction" 一样贵.

(补充:XCHG 等于 LOCK XCHG,但 CMPXCHG 不等于 LOCK CMPXCHG (这真的是原子的)

ARM 和 PowerPC 上的任何`compare_exchange_weak() 对于不同的 std::memory_orders 有不同的锁处理器指令,通过 LL/SC .

x86(CAS 除外)、ARM 和 PowerPC 的处理器内存屏障指令:http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html

最佳答案

您不必担心编译器将给定的 C11 构造映射到哪些指令,因为这不会捕获所有内容。相反,您需要根据 C11 内存模型的保证来开发代码。正如上面的评论所述,只要不违反 C11 内存模型,您的编译器或 future 的编译器就可以自由地重新排序宽松的内存操作。通过 CDSChecker 等工具运行您的代码以查看内存模型下允许哪些行为也是值得的。

关于c++ - x86_64 和 ARM 上的原子 CAS 操作是否始终使用 std::memory_order_seq_cst?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18577584/

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