2013-02-04 17 views
6

thể trùng lặp:
Concurrency: Atomic and volatile in C++11 memory modelĐiều gì C++ 11 <atomic> hoạt động/đơn đặt hàng bộ nhớ đảm bảo độ tươi?

Với đặc điểm kỹ thuật 11 <atomic> C++, là có bất kỳ đảm bảo độ tươi? Các mô tả của các đơn đặt hàng bộ nhớ khác nhau chỉ đối phó với việc sắp xếp lại (theo như tôi đã thấy).

Cụ thể, trong tình huống này:

#include <atomic> 

std::atomic<int> cancel_work(0); 

// Thread 1 is executing this function 
void thread1_func() { 

    ... 

    while (cancel_work.load(<some memory order>) == 0) { 
     ...do work... 
    } 
} 


// Thread 2 executes this function 
void thread2_func() { 

    ... 

    cancel_work.store(1, <some memory order>); 

    ... 

} 

Nếu thread 1 và đề 2 không chia sẻ bất kỳ dữ liệu nào khác ngoài cancel_work, có vẻ như với tôi rằng bất kỳ sự bảo đảm trật tự không cần thiết và std::memory_order_relax cũng đủ cho cả các cửa hàng và tải. Nhưng điều này đảm bảo rằng thread 1 sẽ không bao giờ nhìn thấy bản cập nhật của cancel_work thay vì chỉ liên tục đọc dòng bộ nhớ cache cục bộ của nó mà không bao giờ làm mới nó từ bộ nhớ chính? Nếu không, mức tối thiểu cần thiết để thực hiện bảo lãnh đó là gì?

+1

@UmNyobe Lý do tôi không tìm thấy câu hỏi đó trước khi hỏi tôi là nó dường như là về các chất dễ bay hơi. Câu trả lời là một bản sao, nhưng câu hỏi là imo không phải là điều này sẽ được tìm thấy bởi những người tìm kiếm một cái gì đó khác với câu hỏi "nguyên tử và dễ bay hơi" bạn đề cập đến. – JanKanis

Trả lời

4

Sẽ không có gì đảm bảo rằng: mọi thứ đều sắp đặt hàng. Thậm chí memory_order_seq_cst chỉ đảm bảo rằng mọi thứ diễn ra trong một đơn đặt hàng duy nhất. Về lý thuyết, trình biên dịch/thư viện/cpu có thể lên lịch mọi tải từ cancel_store ở cuối chương trình.

Có một tuyên bố chung trong 29.3p13 rằng

Triển khai nên các cửa hàng nguyên tử có thể nhìn thấy tải nguyên tử trong một khoảng thời gian hợp lý.

Nhưng không có đặc điểm kỹ thuật về những gì cấu thành "khoảng thời gian hợp lý".

Vì vậy: memory_order_relaxed chỉ nên sử dụng tốt, nhưng memory_order_seq_cst có thể hoạt động tốt hơn trên một số nền tảng vì dòng bộ nhớ cache có thể được tải lại sớm hơn.

3

Nó xuất hiện this answer cũng trả lời câu hỏi của tôi. Vâng, hy vọng câu hỏi của tôi sẽ giúp các googlers tìm thấy nó tốt hơn.

Chủ đề 1 "NÊN" xem cập nhật cancel_work trong một khoảng thời gian hợp lý "", tuy nhiên chính xác là hợp lý (rõ ràng) không được chỉ định.

2

Gọi hàm [không được trình biên dịch đưa vào] sẽ tự động tải lại bất kỳ thanh ghi nào chứa các biến không nằm ngay cục bộ. Vì vậy, miễn là bộ vi xử lý chạy thread1_func() đã có bộ nhớ cache-nội dung đỏ bừng hoặc cập nhật dựa trên store, nó sẽ hoạt động.

memory_order_relax phải đảm bảo rằng dữ liệu (vào một thời điểm nào đó trong tương lai) được xóa khỏi bất kỳ bộ xử lý nào khác [đây là tự động trong x86, nhưng không phải tất cả các loại bộ vi xử lý. '], nhưng nó không được đảm bảo xảy ra TRƯỚC KHI bất kỳ ghi nào khác [đối với các biến số nguyên tử hoặc thông thường].

Và lưu ý rằng thứ tự bộ nhớ CHỈ ảnh hưởng đến chuỗi/bộ xử lý hiện tại. Một chuỗi hoặc bộ xử lý khác làm gì trong thời gian lưu trữ hoặc tải hoàn toàn phụ thuộc vào luồng/bộ xử lý đó.Ý tôi là, thread1_func() trong trường hợp của bạn có thể đọc giá trị 0 trong một khoảng thời gian ngắn sau khi giá trị 1 được viết bởi bộ xử lý/luồng khác. Tất cả các hoạt động nguyên tử đảm bảo rằng nó EITHER nhận giá trị OLD hoặc giá trị MỚI, không bao giờ có gì đó ở giữa [trừ khi bạn sử dụng memory_order_relax, không thực thi bất kỳ thứ tự tải/lưu trữ nào giữa các hoạt động trong chuỗi. Tuy nhiên, bất cứ thứ tự bộ nhớ nào bạn đang sử dụng, nguyên tử phải đảm bảo [giả sử thực hiện đúng] rằng giá trị cuối cùng được cập nhật. Chỉ khó khăn hơn để nói khi nào trong một trường hợp thoải mái.

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