2014-11-01 18 views
5

Tôi đang sử dụng GCC 4.7.2 trên Debian và nhận lỗi trình liên kết bất cứ khi nào tôi cố sử dụng các tiện ích <atomic> với giá trị 16 byte. Tôi đang chạy một máy ảo x86_64 có thể hỗ trợ các hướng dẫn CMPXCHG16B - nhưng ngay cả khi tôi không có phần cứng cần thiết, tôi không thấy lý do tại sao một lỗi liên kết nên được sản xuất ở đây. Theo như tôi biết, thư viện <atomic> được cho là sẽ quay trở lại bằng cách sử dụng khóa thông thường nếu phần cứng không hỗ trợ hoạt động CAS cần thiết.Lỗi liên kết tham chiếu không xác định khi sử dụng CAS 16 byte với GCC

Dù sao, đây là một trường hợp thử nghiệm rất đơn giản để tái tạo vấn đề này:

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

Khi tôi biên dịch này, tôi nhận được:

# 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 

Lưu ý rằng nếu tôi thay đổi chương trình để foo là chỉ 8 byte, tôi không nhận được lỗi liên kết. Những gì đang xảy ra ở đây?

+0

Thú vị, tôi có thể repro này với g ++ 4.8.2 và kêu vang ++ 3.6. Bạn không chắc chắn vấn đề cơ bản là gì - nhưng có vẻ như một lỗi trong thư viện chuẩn hoặc một số lỗi như vậy. –

Trả lời

6

câu trả lời đơn giản, một khi bạn biết điều đó:

Gọi g++ với -mcx16.

Các g ++ tài liệu nói:

Tùy chọn này sẽ cho phép GCC sử dụng hướng dẫn CMPXCHG16B trong mã được tạo. CMPXCHG16B cho phép hoạt động nguyên tử trên các loại dữ liệu quadword (hoặc oword đôi) 128 bit. Điều này hữu ích cho bộ đếm độ phân giải cao có thể được cập nhật bởi nhiều bộ xử lý (hoặc lõi). Hướng dẫn này được tạo ra như một phần của các hàm dựng sẵn nguyên tử: xem * chú thích Atomic Builtins :: để biết chi tiết.

(Lưu ý rằng điều này không làm việc cho clang - Tôi nghĩ đó là một lỗi)

+0

Huh ... lạ. Tôi nghĩ GCC được cho là sẽ tự động hỗ trợ cmpxchg16b nếu có, hoặc nếu không thì hãy quay trở lại bằng cách sử dụng một khóa – Siler

+0

Vâng, người ta sẽ mong đợi như vậy. Tôi nghĩ rằng nó quay trở lại một số phiên bản đầu tiên của Intel vì tôi có vẻ nhớ rằng AMD đã có nó ngay từ đầu - nhưng không thể nói chắc chắn] của x86-64 không có điều này, hoặc một số như vậy. –

Các vấn đề liên quan