Rov*_*ion 6 c++ double c++11 stdatomic
考虑以下代码:
#include <atomic>
int main(void) {
std::atomic<double> aDouble;
aDouble = 6.0;
}
Run Code Online (Sandbox Code Playgroud)
G ++编译它就好了,而clang ++产生以下内容:
clang++ -std=c++11 Main.cpp
/tmp/Main-d4f0fc.o: In function `std::atomic<double>::store(double, std::memory_order)':
Main.cpp:(.text._ZNSt6atomicIdE5storeEdSt12memory_order[_ZNSt6atomicIdE5storeEdSt12memory_order]+0x31): undefined reference to `__atomic_store_8'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Run Code Online (Sandbox Code Playgroud)
他们没有链接到相同的标准库吗?
如果clang++ -stdlib=libstdc++不能解决您的问题,请链接-latomic来实现这些功能。
不过,请尝试让编译器内联 8 字节和更窄的原子,因为库函数有潜在的巨大缺点。
请注意,库函数不支持弱于 的内存排序memory_order_seq_cst,因此它们始终在 x86 上使用mfence,即使源使用relaxed.
32 位 x86 版本__atomic_store_8更糟糕:它使用lock cmpxchg8bSSE 或 x87 8 字节存储来代替。即使未对齐,它也能正常工作,但性能会受到巨大影响。它还具有两个冗余lock or [esp], 0指令,作为从堆栈加载其参数的额外障碍。(我正在 Arch Linux 上查看/usr/lib32/libatomic.so.1.2.0gcc7.1.1。)
atomic_llong讽刺的是,当前的 gcc -m32 (在 C11 模式下,而不是 C++11)在结构内部对齐不足,但内联movq xmm加载/存储,因此它实际上不是原子的。(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65146#c4)
当前 clang -m32atomic_llong即使在结构内部也对齐到 8 字节(与常规 不同long long,i386 System V ABI 仅对齐到 4B)。具有讽刺意味的是,clang 生成对库函数的调用,该函数使用lock cmpxchg8b( https://bugs.llvm.org/show_bug.cgi?id=33109 ),因此即使存在缓存行拆分,它实际上也是原子的。(为什么自然对齐变量上的整数赋值在 x86 上是原子的?)。
因此,即使某些 gcc 编译的代码将指向未对齐的指针传递给 clang,clang 也是安全的_Atomic long long。但它与 gcc 关于结构布局的观点不一致,因此只有直接获取指向原子变量而不是包含结构的指针时,这才有帮助。
相关:x86_64 上的原子双浮点或 SSE/AVX 矢量加载/存储