2013-05-06 39 views
5

Tôi hỏi cụ thể về ý nghĩa của mô hình bộ nhớ. http://en.cppreference.com/w/cpp/atomic/memory_orderCác câu lệnh điều kiện C++ có mang phụ thuộc từ biểu thức điều kiện đến câu lệnh không?

Tôi hỏi vì tôi muốn biết nếu tôi có thể sử dụng một std::memory_order_consume ở dưới đây:

mLocalMemPtr1 và 2 và mAtomicMemPtr là con trỏ vào một bộ đệm chia sẻ.

Trong một sợi sản xuất tôi đang làm:

for (int x = 0; x < 10; ++x) 
{ 
    ++mLocalMemPtr1 
    *mLocalMemPtr1 = x;  // <========= A 
    mAtomicMemPtr.store(mLocalMemPtr1, std::memory_order_release); 
} 

Và trong người tiêu dùng:

tempMemPtr = mAtomicMemPtr.load(std::memory_order_consume); 
while (tempMemPtr != mLocalMemPtr2) 
{ 
    ++mLocalMemPtr2; 
    int test = *mLocalMemPtr2; // <======== B 
    doSomeLongRunningThing(test); 
    tempMemPtr = mAtomicMemPtr.load(std::memory_order_consume); 
} 

Vì vậy, hiện chuỗi phụ thuộc đi tempMemPtr -> mLocalMemPtr2 -> test -> doSomeLongRunningThing?

Tôi đặc biệt lo lắng rằng B có thể được thực thi trước A. Tôi biết tôi có thể sử dụng một std::memory_order_acquire, nhưng tôi có thể sử dụng tiêu thụ (đó là nhẹ hơn) nếu tuyên bố điều kiện gây ra một sự phụ thuộc thứ tự bộ nhớ.

Trả lời

0

Tôi tin rằng với consume đặt hàng, trình biên dịch có thể thực sự tạo bản sao toàn bộ trước mSharedBuffer. Bạn cần acquire ngữ nghĩa để vô hiệu hóa các bản sao của các biến được lưu trong bộ nhớ cache trước đây trừ mAtomicMemLocPtr .

2

CppReference:

Release-tiêu thụ đặt hàng

Nếu một cửa hàng nguyên tử trong chủ đề A được gắn thẻ std :: memory_order_release và một tải nguyên tử trong chủ đề B từ biến tương tự được gắn thẻ std :: memory_order_consume , tất cả bộ nhớ ghi (nguyên tử và nguyên tử thoải mái) là phụ thuộc được đặt hàng trước cửa hàng nguyên tử từ quan điểm của luồng A, trở thành tác dụng phụ có thể nhìn thấy trong sợi B, nghĩa là, khi tải nguyên tử là hoàn thành, thread B được đảm bảo để xem tất cả mọi thứ mà thread A đã viết cho bộ nhớ nếu nó mang phụ thuộc dữ liệu vào tải nguyên tử.

1.10.10:

Một đánh giá A được sự phụ thuộc theo lệnh trước khi đánh giá B nếu

- Một thực hiện một hoạt động phát hành trên một đối tượng M nguyên tử, và, trong chủ đề khác, B thực hiện một hoạt động tiêu thụ trên M và đọc một giá trị được viết bởi bất kỳ tác dụng phụ trong chuỗi phát hành do A (...)

1.10.9:

Một đánh giá Một mang một phụ thuộc vào việc đánh giá B nếu - giá trị của A được sử dụng như một toán hạng B, trừ khi:

- B là một lời kêu cầu của bất kỳ chuyên môn của std :: kill_dependency (29.3), hoặc

- A là toán hạng trái của một nhà điều hành được xây dựng trong logic AND (& &, xem 5.14) hoặc logic OR (||, xem 5,15), hoặc

- A là bên trái toán hạng của toán tử có điều kiện (?:, xem 5.16) hoặc

- A là toán hạng bên trái của toán tử dấu phẩy (,) được xây dựng sẵn (5.18); (...)

Căn cứ vào những sự kiện này tôi cần phải đồng bộ hóa mLocalMemPtr2. Tuy nhiên vẫn còn một câu hỏi về thứ tự đánh giá.

if (atomic.load(std::consume) < x) 

Cái nào được đánh giá trước không được chỉ định. Có không có bảo đảm (vì tôi không thể tìm thấy nó trong tiêu chuẩn) mà trình biên dịch đầu tiên sẽ thực hiện thao tác tiêu thụ, làm mới bộ đệm được chia sẻ và sau đó tải atomicvà sau đóx. Đã không tìm thấy bằng chứng cho thấy toán hạng được đánh giá theo cách "muốn", tôi nói rằng không có sự phân hủy rõ ràng của tải nguyên tử mLocalMemPtr2 nó sẽ không hoạt động và CPU có thể đọc giá trị cũ của bộ nhớ được chỉ bởi mLocalMemPtr2. memory_order_acquire sẽ không thay đổi nhiều ở đây, vì mLocalMemPtr2 mang phụ thuộc dữ liệu.

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