2014-11-01 4 views
5

Ich verwende GCC 4.7.2 unter Debian und erhalte Linker-Fehler, wenn ich versuche, die <atomic>-Funktionen mit 16-Byte-Werten zu verwenden. Ich benutze eine x86_64-VM, die die CMPXCHG16B-Anweisung unterstützen kann - aber selbst wenn ich nicht die notwendige Hardware hatte, sehe ich nicht, warum hier ein Linker-Fehler erzeugt werden sollte. Soweit ich weiß, soll die Bibliothek <atomic> auf normale Sperren zurückgreifen, wenn die Hardware die notwendige CAS-Operation nicht unterstützt.Undefinierter Referenz-Linker-Fehler bei Verwendung von 16-Byte-CAS mit GCC

Wie auch immer, hier ist ein sehr einfacher Testfall, dieses Problem zu reproduzieren:

#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); 
} 

Wenn ich dies zu kompilieren, erhalte ich:

# 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 

Beachten Sie, dass, wenn ich das Programm ändern, so dass foo ist nur 8 Bytes, bekomme ich nicht den Linker-Fehler. Was ist denn hier los?

+0

Interessant, kann ich das mit g ++ 4.8.2 und Klirren repro ++ 3.6. Nicht sicher, was das zugrunde liegende Problem ist - aber scheint wie ein Fehler in der Standard-Bibliothek, oder so ähnlich. –

Antwort

6

Einfache Antwort, wenn Sie es wissen:

Invoke g++ mit -mcx16.

Die g ++ docs sagen:

Diese Option GCC ermöglicht CMPXCHG16B Anweisung in generierten Code zu verwenden. CMPXCHG16B ermöglicht atomare Operationen für 128-Bit-Double-Quadword- (oder OWORD-) Datentypen. Dies ist nützlich für Hochauflösungszähler, die durch mehrere Prozessoren (oder Kerne) aktualisiert werden können. Dieser Befehl wird als Teil von Atomic Built-in-Funktionen generiert: siehe * Note Atomic Builtins :: für Details.

(Beachten Sie, dass dies nicht für clang funktioniert - ich denke, dass ein Fehler ist)

+0

Huh ... seltsam. Ich würde denken, GCC soll automatisch cmpxchg16b unterstützen, wenn verfügbar, oder sonst auf eine Sperre zurückgreifen – Siler

+0

Ja, würde man so erwarten. Ich denke, dass es auf einige frühe Versionen von Intel zurückgeht, da ich mich daran erinnere, dass AMD es von Anfang an hatte - aber ich kann es nicht sicher sagen. X86-64 hatte das nicht, oder so etwas. –