Tôi đã cảm thấy rằng tải bộ nhớ không thể được nâng lên trên một tải thu được trong mô hình bộ nhớ C++ 11. Tuy nhiên, nhìn vào mã mà gcc 4.8 tạo ra chỉ có vẻ đúng với các tải nguyên tử khác, không phải tất cả bộ nhớ. Nếu đó là sự thật và mua tải không đồng bộ hóa tất cả bộ nhớ (chỉ std::atomics
) sau đó tôi không chắc chắn làm thế nào nó sẽ có thể thực hiện mutexes mục đích chung về std :: nguyên tử.Nâng tải trọng không nguyên tử lên thông qua việc mua các tải nguyên tử
Các mã sau đây:
extern std::atomic<unsigned> seq;
extern std::atomic<int> data;
int reader() {
int data_copy;
unsigned seq0;
unsigned seq1;
do {
seq0 = seq.load(std::memory_order_acquire);
data_copy = data.load(std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_acquire);
seq1 = seq.load(std::memory_order_relaxed);
} while (seq0 != seq1);
return data_copy;
}
Tạo:
_Z6readerv:
.L3:
mov ecx, DWORD PTR seq[rip]
mov eax, DWORD PTR data[rip]
mov edx, DWORD PTR seq[rip]
cmp ecx, edx
jne .L3
rep ret
nào có vẻ đúng với tôi.
Tuy nhiên thay đổi dữ liệu là một int
hơn std::atomic
:
extern std::atomic<unsigned> seq;
extern int data;
int reader() {
int data_copy;
unsigned seq0;
unsigned seq1;
do {
seq0 = seq.load(std::memory_order_acquire);
data_copy = data;
std::atomic_thread_fence(std::memory_order_acquire);
seq1 = seq.load(std::memory_order_relaxed);
} while (seq0 != seq1);
return data_copy;
}
Tạo này:
_Z6readerv:
mov eax, DWORD PTR data[rip]
.L3:
mov ecx, DWORD PTR seq[rip]
mov edx, DWORD PTR seq[rip]
cmp ecx, edx
jne .L3
rep ret
Vì vậy, những gì đang xảy ra?
Nếu bạn viết lại các op nguyên tử để 'tải (rel); hàng rào (acq); 'trong phiên bản thứ hai, hiện đầu ra asm của nó? – yohjp
@yoyjp Bạn đang đề cập đến việc tải 'seq0'? Nếu vậy thì không, nó không ảnh hưởng đến mã được tạo ra ở tất cả. – jleahy
Không, tôi đã đề cập 'seq1'. Một "thu thập hàng rào" mà đã có được ngữ nghĩa là bao gồm 'seq1.load (thư giãn) -> hàng rào (có được)' lệnh ops, không phải 'hàng rào (có được) -> seq1.load (thư giãn)' trong bộ nhớ C++ 11 mô hình. "Hàng rào" của C++ ** chỉ ảnh hưởng _happens-trước mối quan hệ_ giữa các hoạt động nguyên tử hoặc/và hàng rào, nó có ** không ** tác động trực tiếp lên các vars phi nguyên tử. Trong thời điểm này, "hàng rào" của C++ khá khác với hướng dẫn rào cản bộ nhớ của trình biên dịch/bộ biên dịch (như mfence của x86). – yohjp