Wenn clang++ -stdlib=libstdc++
Ihr Problem nicht löst, verknüpfen Sie mit -latomic
für die Implementierung dieser Funktionen.
Versuchen Sie, Ihren Compiler zu Inline-8-Byte- und engeren Atomics zu bekommen, da die Bibliotheksfunktionen möglicherweise große Nachteile haben.
Beachten Sie, dass die Bibliotheksfunktionen nicht unterstützen einen Speicher schwächer als memory_order_seq_cst
Bestellung, so dass sie immer Verwendung mfence
auf x86, auch wenn die Quelle relaxed
verwendet.
Die 32-Bit-x86-Version von __atomic_store_8
ist noch schlimmer: Es verwendet lock cmpxchg8b
anstelle eines SSE oder x87 8-Byte-Speichers. Dies macht es funktioniert, auch wenn es falsch ausgerichtet ist, aber mit einer massiven Leistungseinbuße. Es hat auch zwei redundante lock or [esp], 0
Anweisungen als zusätzliche Barrieren um seine Argumente vom Stapel zu laden. (Ich bin bei /usr/lib32/libatomic.so.1.2.0
von gcc7.1.1 auf Arch Linux suchen.)
Ironischerweise aktuelle gcc -m32 (in C11-Modus nicht C++ 11) unter ausrichtet atomic_llong
innerhalb einer Struktur, aber inlines movq xmm
Lasten/speichert, also ist es nicht wirklich atomar. (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65146#c4)
Current Klirren -m32 atomic_llong
zu 8 Byte sogar innerhalb structs ausrichtet (im Gegensatz zu regulären long long
, die der i386 System V ABI richtet sich nur auf 4B). Die Ironie ist, dass Clam Aufrufe an die Bibliotheksfunktionen generiert, die eine lock cmpxchg8b
verwenden, so dass sie sogar bei Cache-Zeilenaufteilungen atomar ist. (Why is integer assignment on a naturally aligned variable atomic?). Daher ist clang sicher, selbst wenn irgendein gcc-kompilierter Code ihm einen Zeiger auf eine fehlausgerichtete _Atomic long long
übergibt. Aber es stimmt nicht überein mit gcc über Struktur-Layout, so dass dies nur helfen kann, wenn es einen Zeiger auf die atomare Variable direkt erhält, anstatt die umgebende Struktur.
Meistens verwendet clang libC++, während gcc libstdC++ verwendet. –
Wenn Sie also mit Clang auf einem System kompilieren, auf dem nur die GCC-Standardbibliothek installiert ist, müssen Sie wahrscheinlich das Flag "-lstdC++" an Clang übergeben. – 5gon12eder
Ja, 'clang ++ -std = C++ 11 -lstdC++ Main.cpp' kompiliert tatsächlich das Programm. Es ist also eine Sache von 'libC++', das Feature nicht implementiert zu haben, während 'libstdC++' es hat? – Rovanion