如果用 memory_order_acquire 存储会发生什么
what happened if store with memory_order_acquire
据我们所知:
加载 memory_order_acquire,
与 memory_order_release 一起存储
然而,
我发现用gcc4.8.2,打开-O2,抛出一个编译错误,
/usr/include/c++/4.8.2/atomic:199:9: 错误:'__atomic_store' 的内存模型无效
但是如果关闭-O2,错误就消失了
此外,如果使用 gcc8.3.0,即使使用 -O2
也会抛出错误
所以发生了什么事?这怎么解释?
如果不进行优化,order
作为编译时常量对内置编译器来说是不可见的,GCC 只是将运行时变量顺序视为 seq_cst
(而不是在值上分支以跳过 mfence
)。常量传播需要优化,以使检查非法的 order
的编译器逻辑可见,并给出预期的错误。
std::atomic<T>::store()
是一个用 C++ 编写的函数,它接受一个 order
arg 并将该变量传递给 GNU C 内置函数 __atomic_store
.
如果不进行优化,就不会发生持续传播。 Why does clang produce inefficient asm with -O0 (for this simple floating point sum)?. Even __attribute__((always_inline))
doesn't make the compiler optimize when inlining, it just avoids having an actual function call.
如果您查看生成的未优化 asm,甚至还有对 std::operator&(std::memory_order, std::__memory_order_modifier)
https://godbolt.org/z/dhViAG 的非内联调用。但是原子存储本身是内联的。
据我们所知: 加载 memory_order_acquire, 与 memory_order_release 一起存储 然而, 我发现用gcc4.8.2,打开-O2,抛出一个编译错误, /usr/include/c++/4.8.2/atomic:199:9: 错误:'__atomic_store' 的内存模型无效 但是如果关闭-O2,错误就消失了
此外,如果使用 gcc8.3.0,即使使用 -O2
也会抛出错误所以发生了什么事?这怎么解释?
如果不进行优化,order
作为编译时常量对内置编译器来说是不可见的,GCC 只是将运行时变量顺序视为 seq_cst
(而不是在值上分支以跳过 mfence
)。常量传播需要优化,以使检查非法的 order
的编译器逻辑可见,并给出预期的错误。
std::atomic<T>::store()
是一个用 C++ 编写的函数,它接受一个 order
arg 并将该变量传递给 GNU C 内置函数 __atomic_store
.
如果不进行优化,就不会发生持续传播。 Why does clang produce inefficient asm with -O0 (for this simple floating point sum)?. Even __attribute__((always_inline))
doesn't make the compiler optimize when inlining, it just avoids having an actual function call.
如果您查看生成的未优化 asm,甚至还有对 std::operator&(std::memory_order, std::__memory_order_modifier)
https://godbolt.org/z/dhViAG 的非内联调用。但是原子存储本身是内联的。