簡體   English   中英

如何測試 std::memory_order_relaxed 的行為?

[英]How to test the behavior of std::memory_order_relaxed?

我已閱讀std::memory_order_relaxed的文檔。

放寬排序的解釋之一是......

 // Thread 1: r1 = y.load(memory_order_relaxed); // A x.store(r1, memory_order_relaxed); // B // Thread 2: r2 = x.load(memory_order_relaxed); // C y.store(42, memory_order_relaxed); // D

對此的解釋是......

[它] 允許產生r1 == r2 == 42 特別是,如果 D 在線程 2 中的 C 之前完成,則可能會發生這種情況,這是由於編譯器重新排序或在運行時。

我已經理解了解釋,並嘗試在我的電腦上測試如下代碼:

std::atomic<int> x = {0};
std::atomic<int> y = {0};

int r1, r2;

void task1() {
    // Thread 1:
    r1 = y.load(memory_order_relaxed); // A
    x.store(r1, memory_order_relaxed); // B
}

void task2() {
   // Thread 2:
    r2 = x.load(memory_order_relaxed); // C 
    y.store(42, memory_order_relaxed); // D
}


int main()
{
    std::thread t2 (task2);
    std::thread t1 (task1);

    t1.join();
    t2.join();

    cout << "r1: " << r1
        << "\nr2: " << r2 << endl;

    return 0;
}

此代碼的結果永遠不會r1 == r2 == 42 ,據說這是該文檔中的一種可能行為。

這段代碼有什么問題嗎? 或者,有什么誤解嗎?

或者,有什么誤解嗎?

是的,有一個。 std::memory_order_relaxed在您的程序中允許的內容是針對架構的實現(編譯器),以生成可能觀察到副作用r1 == r2 == 42

實現不必產生這樣的程序,這樣的程序也不必產生​​副作用; 無論如何,這是一個可能的結果。

如何測試 std::memory_order_relaxed 的行為?

我看不到這個問題的一般解決方案。 您只能檢查觀察到的副作用是否std::memory_order_relaxed的規格相匹配。

您的代碼有點幼稚,因為當第二個線程開始時,第一個線程可能已經完成。 線程需要真正並發地運行這些代碼段。

要使r1 == r2 == 42為真,它需要將加載C重新排序到存儲D ,x86 不會當前存儲之后重新排序加載,因此您可能永遠不會在此平台上觀察到這種重新排序(除非編譯器重新排序) CD )。

另一方面,ARM 和 PowerPC 的內存模型較弱。 請參閱運行時內存排序表。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM