使用带GCC的16字节CAS时未定义的引用链接器错误

Sil*_*ler 5 c++ atomic c++11

我在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个字节,我不会收到链接器错误.这里发生了什么?

Mat*_*son 7

简单回答,一旦你知道它:

调用g++-mcx16.

g ++文档说:

该选项将使GCC能够在生成的代码中使用CMPXCHG16B指令.CMPXCHG16B允许对128位双四字(或oword)数据类型进行原子操作.这对于可由多个处理器(或核心)更新的高分辨率计数器非常有用.该指令是作为原子内置函数的一部分生成的:有关详细信息,请参阅*note Atomic Builtins ::.

(注意,这不起作用clang- 我认为这是一个错误!)

  • 从 GCC 开始:“编译器使用此指令来实现 __sync 内置函数。但是,对于在 128 位整数上操作的 __atomic 内置函数,始终使用库调用。” (2认同)