簡體   English   中英

C++11 中的內存排序是關於主內存刷新排序的嗎?

[英]Is memory ordering in C++11 about main memory flush ordering?

我不確定我是否完全理解(我可能都錯了)C++11 中原子性和內存排序的概念。 讓我們以這個簡單的單線程示例為例:

int main()
{
    std::atomic<int> a(0);
    std::atomic<int> b(0);
    a.store(16);
    b.store(10);

    return 0;
}

在這個單線程代碼中,如果 a 和 b 不是原子類型,編譯器可能會以在匯編代碼中的方式重新排序指令,例如,我有一個移動指令,在移動指令之前將 10 分配給“b”將 16 分配給“a”。 所以對我來說,作為原子變量,它保證我在“b 移動指令”之前有“a 移動指令”,正如我在我的源代碼中所說的那樣。 在那之后,是帶有執行單元、預取指令和亂序框的處理器。 並且該處理器可以在“a 指令”之前處理“b 指令”,無論匯編代碼中的指令順序如何。 因此,在將 16 個存儲在寄存器/存儲緩沖區或緩存中之前,我可以將 10 個存儲在寄存器或處理器的存儲緩沖區或緩存中。

根據我的理解,這就是內存排序模型出現的地方。 從那一刻起,如果我讓默認模型按順序保持一致。 向我保證在主內存中清除這些值(10 和 16)將尊重我在源代碼中進行存儲的順序。 這樣處理器將開始刷新寄存器或緩存,其中 16 存儲在主存儲器中以用於更新“a”,然后它將在主存儲器中刷新 10 以用於“b”。

所以這種行為確實讓我明白,如果我使用寬松的內存模型。 只有最后一部分不能保證,因此主存中的flush可能會完全混亂。

對不起,如果你讀我有困難,我的英語仍然很差。 但是謝謝你們的時間。

C++ 內存模型是關於抽象機器和值的可見性,而不是關於“主內存”、“寫隊列”或“刷新”之類的具體事物。

在您的示例中,內存模型指出,由於寫入a發生在寫入b之前,因此從b讀取 10 的任何線程必須在隨后從a讀取時看到 16 (除非此后已被覆蓋,當然)。

這里重要的是建立先發生的關系和價值可見性。 這如何映射到緩存和內存取決於編譯器。 在我看來,最好停留在那個抽象級別,而不是試圖將模型映射到您對硬件的理解,因為

  • 您對硬件的理解可能是錯誤的。 硬件甚至比 C++ 內存模型更復雜。
  • 即使您現在的理解是正確的,更高版本的硬件可能具有不同的模型,至少在子系統中是這樣。
  • 通過映射到硬件模型,您可能會對不同硬件模型的影響做出錯誤的假設。 例如,如果您了解內存模型如何映射到 x86 硬件,您就不會理解 PowerPC 上消耗和獲取之間的細微差別。
  • C++ 模型非常適合推理正確性。

您沒有指定您使用的架構,但基本上每個架構都有自己的內存排序模型(有時您可以選擇不止一個),並且作為“合同”。 編譯器應該意識到這一點,並相應地使用輕量級或重量級指令來保證它需要什么才能提供語言的內存模型。

引擎蓋下的硬件實現可能非常復雜,但簡而言之 - 您無需刷新即可獲得全局可見性。 現代緩存系統提供監聽功能,這樣一個值可以全局可見和全局排序,同時仍然駐留在一些私有核心緩存中(並且在較低的緩存級別有陳舊的副本),MESI 協議控制如何正確處理它。

寫入的生命周期從亂序引擎開始,在那里它仍然是推測性的(即 - 可以由於較舊的分支預測錯誤或故障而被清除)。 自然,那段時間從外面是看不到寫的,所以這里的亂序執行是無關緊要的。 一旦提交,如果系統保證存儲排序(如 x86),它仍然必須排隊等待輪到它變得可見,因此它被緩沖。 其他內核無法看到它,因為它的觀察時間尚未到達(盡管該內核中的本地負載可能會在 x86 的某些實現中看到它 - 這是 TSO 和真正順序一致性之間的區別之一)。 一旦舊的存儲完成,存儲可能會變得全局可見——它不必為此去核心之外的任何地方,它可以保持在內部緩存。 事實上,一些 CPU 甚至可能在仍處於存儲緩沖區時使其可觀察,或者推測性地將其寫入緩存 - 實際決策點是何時使其響應外部窺探,其余的是實現細節。 具有更寬松順序的架構可能會更改順序,除非被柵欄/障礙明確阻止。

基於此,您的代碼片段無法在 x86 上重新排序存儲,因為存儲不會在那里彼此重新排序,但它可能能夠在例如 arm 上這樣做。 如果在這種情況下語言需要強排序,編譯器將不得不決定它是否可以依賴硬件,或者添加一個柵欄。 無論哪種方式,任何從另一個線程(或套接字)讀取此值的人都必須窺探它,並且只能看到響應的寫入。

暫無
暫無

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

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