gpt4 book ai didi

c++ - 非 const 左值传递时 memory_order 更改为默认值

转载 作者:太空宇宙 更新时间:2023-11-04 13:09:21 25 4
gpt4 key购买 nike

#include <atomic>

std::atomic<int> val{1};

const auto my_order = std::memory_order_relaxed; // const lvalue

int main()
{
val.store(42, my_order);
}

此代码无关紧要,但我注意到内存排序方面有些奇怪。编译器为 main(x86_64,g++ 6.2.1,使用 -O3 编译)生成以下程序集:

0x00000000004004c0 <+0>:     movl   $0x2a,0x200b5a(%rip)        # 0x601024 <val>
0x00000000004004ca <+10>: xor %eax,%eax
0x00000000004004cc <+12>: retq

没有特殊的 CPU 指令来处理 x86 上预期具有 std::memory_order_relaxed 排序的原子。
但是,当 const 限定符从 my_order

中移除时
auto my_order = std::memory_order_relaxed; // non-const lvalue

编译器生成的程序集变为:

0x00000000004004c0 <+0>:     movl   $0x2a,0x200b5a(%rip)        # 0x601024 <val>
0x00000000004004ca <+10>: xor %eax,%eax
0x00000000004004cc <+12>: mfence
0x00000000004004cf <+15>: retq

mfence 指令似乎表明现在使用了 std::memory_order_seq_cst 排序(默认)。这让我有点惊讶。尽管 my_order 是一个左值(非常规地指定内存顺序),但它是按值传递的(仍然是 std::memory_order_relaxed)而且我看不出如何非 const 会改变结果。为此,我在库头文件中找不到特定的重载。
对于 clang,我看到了类似的结果,除了它使用 xchg,这是表达顺序一致性的 clang 方式。
什么可以解释差异?

最佳答案

通常,当编译器无法证明排序参数在编译时已知时,它不会冒险并假设最坏情况。

如果 my_order 是一个非 const 全局变量,编译器无法知道执行 store 时的实际值是什么因此它将使用 std::memory_order_seq_cst。如果变量声明为const,则排序参数将生效,mfence 指令将消失。

关于c++ - 非 const 左值传递时 memory_order 更改为默认值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40644922/

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