我在Debian上使用GCC 4.7.2,并且每当我尝试使用<atomic>
具有16字节值的工具时都会收到链接器错误.我正在运行一个可以支持该CMPXCHG16B
指令的x86_64 VM - 但即使我没有必要的硬件,我也不明白为什么应该在这里生成链接器错误.据我所知,<atomic>
如果硬件不支持必要的CAS操作,那么库应该依赖于使用常规锁.
无论如何,这是一个非常简单的测试用例来重现这个问题:
#include <atomic>
#include <cstdint>
struct foo
{
std::uint64_t x;
std::uint64_t y;
};
int main()
{
std::atomic<foo> f1({0,0});
foo f2 = {0,0};
foo f3 = {1,1};
f1.compare_exchange_strong(f2, f3);
}
Run Code Online (Sandbox Code Playgroud)
当我编译这个时,我得到:
# g++ test.cpp -o test -std=c++11 -g3
/tmp/ccziKZis.o: In function `std::atomic<foo>::compare_exchange_strong(foo&, foo, std::memory_order, std::memory_order)':
/usr/include/c++/4.7/atomic:259: undefined reference to `__atomic_compare_exchange_16'
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
请注意,如果我更改程序foo
只有8个字节,我不会收到链接器错误.这里发生了什么?
简单回答,一旦你知道它:
调用g++
带-mcx16
.
g ++文档说:
该选项将使GCC能够在生成的代码中使用CMPXCHG16B指令.CMPXCHG16B允许对128位双四字(或oword)数据类型进行原子操作.这对于可由多个处理器(或核心)更新的高分辨率计数器非常有用.该指令是作为原子内置函数的一部分生成的:有关详细信息,请参阅*note Atomic Builtins ::.
(注意,这不起作用clang
- 我认为这是一个错误!)