Nếu clang++ -stdlib=libstdc++
không giải quyết được sự cố của bạn, hãy liên kết với -latomic
để triển khai các chức năng này.
Hãy thử tải trình biên dịch của bạn về nguyên tử 8 byte và hẹp hơn, vì các hàm thư viện có các nhược điểm lớn tiềm ẩn.
Ghi chú rằng chức năng thư viện không hỗ trợ một bộ nhớ đặt hàng yếu hơn memory_order_seq_cst
, vì vậy họ luôn sử dụng mfence
trên x86, thậm chí nếu nguồn sử dụng relaxed
.
Phiên bản 32 bit x86 của __atomic_store_8
thậm chí còn tệ hơn: nó sử dụng lock cmpxchg8b
thay vì một cửa hàng 8-byte SSE hoặc x87 8 byte. Điều này làm cho nó hoạt động ngay cả khi nó không chính xác, nhưng tại một hình phạt hiệu suất lớn. Nó cũng có hai hướng dẫn dư thừa lock or [esp], 0
làm các rào cản thêm xung quanh tải đối số của nó từ ngăn xếp. (Tôi nhìn vào /usr/lib32/libatomic.so.1.2.0
từ gcc7.1.1 trên Arch Linux.)
Trớ trêu thay, -m32 gcc hiện tại (trong chế độ C11, không phải C++ 11) dưới Canh lề atomic_llong
bên trong một cấu trúc, nhưng inlines movq xmm
tải/cửa hàng, vì vậy nó không thực sự nguyên tử. (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65146#c4)
Hiện tại clang -m32 sắp xếp atomic_llong
đến 8 byte ngay cả bên trong cấu trúc (không giống như thường lệ long long
, mà hệ thống i386 V ABI chỉ căn chỉnh với 4B). Điều trớ trêu là clang tạo ra các cuộc gọi đến các hàm thư viện, sử dụng một số lock cmpxchg8b
vì vậy nó thực sự là nguyên tử ngay cả với các phần tách dòng bộ nhớ cache. (Why is integer assignment on a naturally aligned variable atomic?). Vì vậy, clang là an toàn ngay cả khi một số mã gcc biên dịch vượt qua nó một con trỏ đến một sai lệch _Atomic long long
. Nhưng nó không đồng ý với gcc về cấu trúc bố trí, do đó, điều này chỉ có thể giúp đỡ nếu nó được một con trỏ đến biến nguyên tử trực tiếp, chứ không phải là cấu trúc có chứa.
Nguồn
2017-09-05 07:49:01
Chủ yếu là clang sử dụng libC++ trong khi gcc sử dụng libstdC++. –
Do đó, nếu bạn đang biên dịch với Clang trên một hệ thống chỉ cài đặt thư viện chuẩn GCC, bạn có thể cần phải chuyển cờ '-lstdC++' sang Clang. – 5gon12eder
Có, 'clang ++ -std = C++ 11 -lstdC++ Main.cpp' thực sự biên dịch chương trình. Vì vậy, nó là một vấn đề của 'libC++ 'không có thực hiện các tính năng trong khi' libstdC++ 'có nó? – Rovanion