簡體   English   中英

as-if規則是否阻止編譯器重新排序對全局/成員變量的訪問?

[英]Does as-if rule prevent compiler reordering of accesses to global/member variables?

我正在研究編譯器優化(特別是此處的指令重新排序)對多線程程序可能產生的影響。

假設我們有一個讀者線程和一個寫作者線程。

// Global shared data between threads
bool data;
bool flag = false;

// writer.cpp
void writer()
{
    data = true;  // (1)
    flag = true;  // (2)
}

// reader.cpp
void reader()
{
    if (flag)
    {
       count << data;
    }
}

可以使用符合C ++ 11的編譯器對指令(1)(2)重新排序嗎?

根據C ++的“假設”規則,轉換不應更改程序的可觀察行為。 顯然,在編譯writer時,編譯器通常無法確定重新排序(1)(2)是否會更改程序的可觀察行為,因為dataflag都是全局變量,可能會影響另一個線程的可觀察行為。

但它在此聲明可以發生這種重新排序,請參閱編譯時的內存排序

那么我們是否需要(1)(2)之間的編譯器障礙? (我很清楚可能的CPU重新排序。這個問題僅適用於編譯器重新排序)

絕對可以。 編譯器沒有義務考慮其他線程或硬件的副作用。

僅當您使用volatile或同步(並且二者不可互換)時,編譯器才被迫考慮這一點。

標准內存模型稱為SC-DRF,或順序一致數據競爭免費。 數據競爭正是您剛剛描述的情景 - 其中一個線程正在觀察非同步變量而另一個線程正在變異。 這是未定義的行為。 實際上,標准明確地賦予編譯器自由,假設沒有其他線程或硬件正在讀取非易失性非同步變量。 編譯器在此基礎上進行優化是絕對合法的。

順便說一下,該鏈接有點廢話。 他的“修復”並沒有解決任何問題。 多線程代碼的唯一正確解決方法是使用同步。

您已經在一周半前的comp.lang.c ++。mode中提出了這個問題,並且已獲得有關C ++ 11對單個線程內排序和“之前發生”的要求之間的關系的完整說明。線程之間的同步關系,請參見: https//groups.google.com/forum/#!topic / comp.lang.c ++。moderated / 43_laZwVXYg

您不了解該回復的哪一部分,我們可以再試一次?

暫無
暫無

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

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