C++ undefined reference to `__atomic_load_16'
Asked Answered
I

1

10

I have linking errors, when trying to do an atomic load of a 16 byte block. I have the following code:

#include <atomic>

struct MyStruct{
  long x; long y;
};

struct X{
  std::atomic<MyStruct> myStruct;
};

int main(){
  X x;
  MyStruct s = atomic_load(&x.myStruct);
}

When I compile this with (g++ version 5.3.1):

g++ --std=c++11 test.cpp

I get the error

/tmp/ccrvzLMq.o: In function `std::atomic<MyStruct>::load(std::memory_order) const':
test.cpp:(.text._ZNKSt6atomicI8MyStructE4loadESt12memory_order[_ZNKSt6atomicI8MyStructE4loadESt12memory_order]+0x1c): undefined reference to `__atomic_load_16'
collect2: error: ld returned 1 exit status

If (following a hint in another post) I add the "-latomic" flag, I get the error "/bin/ld: cannot find /usr/lib64/libatomic.so.1.1.0". And indeed that file does not exist.

Any suggestions?

Gavin

Irreligious answered 3/6, 2016 at 11:38 Comment(5)
Install the atomic library using your package manager.Leafage
Try -march=native?Bath
Your hardware does not have native support for 16-bit atomic operations.Claudette
@KerrekSB That worked, thanks!Irreligious
@SamVarshavchik His hardware probably has, but GCC is very conservative with backwards compatibility to old X86/X64 CPUs. The compiler makers don't want code to break, because you compile on a new machine and then later run it on a less abled machine.Sletten
P
3

Same problem for Clang compiler, in short word: install libatomic and linking with it. (In RHEL the library named libatomic.so.1 so you may need to -l:libatomic.so.1 to set the name)

https://releases.llvm.org/14.0.0/tools/clang/docs/Toolchain.html#libatomic-gnu

If compiler don't know how to translate your 'c++_atomic_operation_code' into CPU instruction, it would ask for help from libatomic. The default compile arguments make the program runnable on x86/64 CPU more generally, so some CPU instructions are disabled.

On the other side, using libatomic would have chance to execute more mordern instruction with faster speed, see comments below. Thanks for @Peter Cordes

Within -march=native, the compiler could utilize more instruction set to translate code. (your CPU are better than Generial-x86/64-CPU)

Or linking with libatomic to avoid assigning -march.

For example, with using tbb, it would often asked for libatomic to make algorithm generally.

Peculiarize answered 14/3, 2023 at 15:31 Comment(1)
GCC7 and later always call to libatomic for 16-byte load/store, even if you use -mcx16. This turned out to be a lucky decision since libatomic can choose at run-time to use movaps on CPUs that support AVX, sine Intel at least has recently documented that the AVX feature bit implies 16-byte atomic load/store guarantees. (SSE instructions: which CPUs can do atomic 16B memory operations?)Alliterative

© 2022 - 2024 — McMap. All rights reserved.