为什么在使用clang编译时没有实现std :: atomic <double>?</double>

时间:2015-03-07 21:57:51

标签: c++ c++11 double stdatomic

考虑以下代码:

#include <atomic>

int main(void) {
  std::atomic<double> aDouble;
  aDouble = 6.0;
}

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)

他们没有链接到同一个标准库吗?

1 个答案:

答案 0 :(得分:1)

如果clang++ -stdlib=libstdc++无法解决您的问题,请与-latomic关联以实现这些功能。

尝试让编译器内联8字节和更窄的原子,因为库函数可能有很大的缺点。

请注意,库函数不支持比memory_order_seq_cst弱的内存排序,因此它们总是在x86上使用mfence,即使源使用{{1 }}

relaxed的32位x86版本更糟糕:它使用__atomic_store_8而不是SSE或x87 8字节存储。这使得即使它不对齐也可以工作,但是会造成巨大的性能损失。它还有两个冗余的lock cmpxchg8b指令作为从堆栈加载其参数的额外障碍。 (我正在使用Arch Linux上的gcc7.1.1查看lock or [esp], 0。)

具有讽刺意味的是,当前的gcc -m32(在C11模式下,而不是C ++ 11中)在结构内部对齐/usr/lib32/libatomic.so.1.2.0,但内联atomic_llong加载/存储,因此它实际上不是原子的。 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65146#c4

当前clang -m32将movq xmm与8个字节对齐,甚至在结构内部(与常规atomic_llong不同,i386 System V ABI仅与4B对齐)。具有讽刺意味的是,clang会生成对库函数的调用,这些函数使用long longhttps://bugs.llvm.org/show_bug.cgi?id=33109),因此即使使用缓存行拆分它也实际上是原子的。 (Why is integer assignment on a naturally aligned variable atomic on x86?)。

因此,即使某些gcc编译的代码传递指向未对齐lock cmpxchg8b的指针,clang也是安全的。但是它不同意关于结构布局的gcc,所以这只有在它直接获得指向原子变量的指针时才有用,而不是包含结构。

相关:Atomic double floating point or SSE/AVX vector load/store on x86_64