2014-11-01 9 views
5

Utilizzo GCC 4.7.2 su Debian e errori di linker ogni volta che si tenta di utilizzare le strutture <atomic> con valori a 16 byte. Sono in esecuzione una macchina virtuale x86_64 in grado di supportare l'istruzione CMPXCHG16B, ma anche se non avessi l'hardware necessario, non vedo perché qui dovrebbe essere generato un errore del linker. Per quanto ne so, si suppone che la libreria <atomic> ricada sui normali blocchi se l'hardware non supporta l'operazione CAS necessaria.Errore linker di riferimento non definito quando si utilizza CAS a 16 byte con GCC

In ogni caso, ecco un semplice banco di prova per riprodurre questo problema:

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

Quando compilo questo, ottengo:

# 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 

Si noti che se cambio il programma in modo che foo è solo 8 byte, non ottengo l'errore del linker. Cosa sta succedendo qui?

+0

Interessante, posso repro questo con g ++ 4.8.2 e clang ++ 3.6. Non sei sicuro di quale sia il problema di fondo, ma sembra un bug nella libreria standard, o qualcosa del genere. –

risposta

6

Risposta semplice, una volta che lo sai:

Invoke g++ con -mcx16.

Il g ++ documenti dicono:

Questa opzione consentirà a GCC di utilizzare l'istruzione CMPXCHG16B in codice generato. CMPXCHG16B consente le operazioni atomiche sui tipi di dati a doppia quadrupla (o oword) a 128 bit . È utile per i contatori ad alta risoluzione che potrebbero essere aggiornati da più processori (o core). Questa istruzione è generata come parte delle funzioni atomiche integrate : vedere * note Atomic Builtins :: per i dettagli.

(Si noti che questo non funziona per clang -! Credo che questo sia un bug)

+0

Huh ... strano. Penserei che GCC dovrebbe supportare automaticamente cmpxchg16b se disponibile, oppure ricorrere all'utilizzo di un lucchetto – Siler

+0

Sì, ce lo si aspetterebbe. Penso che risalga ad alcune prime versioni [di Intel, dal momento che mi sembra di ricordare che AMD ha avuto fin dall'inizio - ma non posso dirlo con certezza] di x86-64 non aveva questo, o qualcosa del genere. –

Problemi correlati