簡體   English   中英

x86 上的競爭條件

[英]Race condition on x86

有人可以解釋一下這個說法:

shared variables
x = 0, y = 0

Core 1       Core 2
x = 1;       y = 1;
r1 = y;      r2 = x;

x86 處理器上怎么可能有r1 == 0r2 == 0

來源Bartosz Milewski 的“並發語言”

該問題可能是由於涉及指令重新排序的優化而出現的。 換句話說,兩個處理器都可以在分配變量xy之前分配r1r2 ,如果他們發現這會產生更好的性能。 這可以通過添加memory 屏障來解決,這將強制執行排序約束。

引用您在帖子中提到的幻燈片

現代多核/語言打破了順序一致性

關於 x86 架構,最好的閱讀資源是英特爾® 64 和 IA-32 架構軟件開發人員手冊(第8.2 章 Memory 訂購)。 8.2.1 和 8.2.2 節描述了由 Intel486、Pentium、Intel Core 2 Duo、Intel Atom、Intel Core Duo、Pentium 4、Intel Xeon 和 P6 系列處理器實現的內存排序:memory Z20F35E630DAF44DBFA4C3F68F5399DC8處理器稱為 ordering ,與舊 Intel386 架構的程序排序強排序)相反(其中讀取和寫入指令始終按照它們在指令流中出現的順序發出)。

該手冊描述了處理器訂購 memory model 的許多訂購保證(例如, Loads 不會與其他負載一起重新排序,Stores 不會與其他存儲一起重新排序Stores 不會與舊負載一起重新排序等),但它也描述了允許的重新排序規則這導致了 OP 帖子中的競爭條件:

8.2.3.4 加載可能會與早期存儲重新排序到不同的位置

另一方面,如果指令的原始順序被切換:

shared variables
x = 0, y = 0

Core 1       Core 2
r1 = y;      r2 = x;
x = 1;       y = 1;

在這種情況下,處理器保證r1 = 1r2 = 1的情況是不允許的(由於8.2.3.3 Stores Are Not Reordered With Early Load保證),這意味着這些指令永遠不會在單個內核中重新排序。

要將其與不同的架構進行比較,請查看這篇文章: Memory 在現代微處理器中的排序 您可以看到 Itanium (IA-64) 比 IA-32 架構進行了更多的重新排序:

各種架構可能的 CPU 重新排序

On processors with a weaker memory consistency model (such as SPARC, PowerPC, Itanium, ARM, etc.), the above condition can take place because of a lack of enforced cache-coherency on writes without an explicit memory barrier instruction. 所以基本上Core1y之前看到x上的寫入,而Core2x之前看到在y上的寫入。 在這種情況下,不需要完整的柵欄指令......基本上,您只需要在這種情況下強制執行寫入或釋放語義,以便在對那些已經被寫給。 具有強大 memory 一致性模型(如 x86)的處理器架構通常不需要這樣做,但正如 Groo 指出的那樣,編譯器本身可以重新排序操作。 您可以在 C 和 C++ 中使用volatile關鍵字來防止編譯器在給定線程中對操作進行重新排序。 這並不是說volatile會創建線程安全的代碼來管理線程之間讀寫的可見性......需要一個 memory 屏障。 因此,雖然使用volatile仍會創建不安全的線程代碼,但在給定線程內,它將在已編譯的機器代碼級別強制執行順序一致性。

這就是為什么有人說: 線程被認為是有害

問題是兩個線程都沒有強制它的兩個語句之間的任何順序,因為它們不是相互依賴的。

  • 編譯器知道xy沒有別名,因此不需要對操作進行排序。

  • CPU 知道xy沒有別名,因此它可能會重新排序它們以提高速度。 發生這種情況的一個很好的例子是 CPU 檢測到寫入組合的機會。 如果它可以在不違反其一致性 model 的情況下合並一個寫入與另一個寫入。

相互依賴看起來很奇怪,但實際上與任何其他競爭條件沒有什么不同。 直接編寫共享內存線程代碼是相當困難的,這就是為什么要開發並行語言和消息傳遞並行框架的原因,以隔離小型 kernel 的並行危害並消除應用程序本身的危害。

暫無
暫無

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

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