为什么<double>在使用 clang 编译时没有实现 std::atomic?
How come std::atomic<double> isn't implemented when compiling with clang?
考虑以下代码段:
#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)
它们不链接到同一个标准库吗?
clang++ -stdlib=libstdc++
不能解决您的问题,请链接到-latomic
以实现这些函数。
但是,尝试让您的编译器内联 8 字节和更窄的原子学,因为库函数具有潜在的大缺点。
请注意,库函数不支持弱于memory_order_seq_cst
的内存排序,因此它们始终在x86上使用mfence
,即使源使用relaxed
。
32 位 x86 版本的 __atomic_store_8
甚至更糟:它使用 lock cmpxchg8b
而不是 SSE 或 x87 8 字节存储。 这使得它即使未对齐也能工作,但性能会受到巨大的损失。 它还有两个冗余lock or [esp], 0
指令,作为从堆栈加载其参数的额外障碍。 (我正在查看 Arch Linux 上 gcc7.1.1 的/usr/lib32/libatomic.so.1.2.0
。
具有讽刺意味的是,当前的 gcc -m32(在 C11 模式下,而不是 C++11)在结构内部atomic_llong
对齐不足,而是内联movq xmm
加载/存储,因此它实际上不是原子的。 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65146#c4)
当前的clang -m32即使在结构内部也能atomic_llong
到8个字节对齐(与常规long long
不同,i386 System V ABI仅与4B对齐)。具有讽刺意味的是,clang 生成对库函数的调用,该函数使用 lock cmpxchg8b
(https://bugs.llvm.org/show_bug.cgi?id=33109),因此即使使用缓存行拆分,它实际上也是原子的。(为什么在 x86 上自然对齐的变量上的整数赋值是原子的?
所以 clang 是安全的,即使一些 gcc 编译的代码向它传递指向未对齐_Atomic long long
的指针。 但是它不同意 gcc 关于结构布局的观点,因此这只有在直接获得指向原子变量而不是包含结构的指针时才有帮助。
相关:原子双浮点或SSE/AVX矢量加载/存储在x86_64
- 如果没有malloc,链表实现将失败
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 如何从 std::atomic 中提取指针 T<T>?
- 实现无开销push_back的最佳方法是什么
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- std::atomic和std::condition_variable wait,notify_*方法之间的区别
- 实现一个在集合上迭代的模板函数
- std::atomic是如何实现的
- 为什么标准库不以无锁的方式为 8 字节以下的结构实现 std::atomic?
- 使用 std::atomic 实现无锁结构,Dtor 崩溃
- 如何使用 C++11 实现指向整数的指针的原子增量<atomic>?
- 为什么<double>在使用 clang 编译时没有实现 std::atomic?
- 如何实现std::atomic::load
- 如何在 std::atomic 上实现一个简单的自旋锁<T>,以便编译器不会对其进行优化?
- C++ 11 标准是否保证 std::atomic<> 作为无锁操作实现?
- C++11 使用标头 '' 实现自旋锁<atomic>
- 如何使用 std::atomic 实现无锁计数器
- C++ std::atomic:<bool>:fetch_or 未实现?