我記得在我上大學的課程中,我最喜歡的一個競賽條件示例是其中一個簡單的main()
方法啓動了兩個線程,其中一個線程增加了一個共享(全局)一個變量,另一個遞減。僞代碼:雙CPU機器上的線程合作
static int i = 10;
main() {
new Thread(thread_run1).start();
new Thread(thread_run2).start();
waitForThreads();
print("The value of i: " + i);
}
thread_run1 {
i++;
}
thread_run2 {
i--;
}
教授接着問什麼i
值一百萬十億數不勝數運行之後。 (如果它基本上是10以外的任何東西)。不熟悉多線程系統的學生回答說,100%的時間,print()
聲明總是將i
報告爲10.
這實際上是不正確的,因爲我們的教授表明,作爲3條語句的每個增量/減量語句實際上編譯(組裝):
1: move value of 'i' into register x
2: add 1 to value in register x
3: move value of register x into 'i'
因此,i
的值可以是9,10或11(I不會進入細節。)
我的問題:
這是(是?)我的理解是物理寄存器集是特定於處理器的。在使用雙CPU機器時(注意雙核和雙CPU之間的區別),每個CPU都有自己的一組物理寄存器嗎? 我以爲答案是肯定的。
在單CPU(多線程)機器上,上下文切換允許每個線程擁有自己的虛擬寄存器集。由於雙CPU機器上有兩套物理寄存器,因此不會因競爭條件而導致更大的潛在可能性,因爲您可以從字面上同時運行兩個線程,而不是單線程上的「虛擬」同時操作, CPU機器? (虛擬同時操作是指參考每個上下文開關保存/恢復寄存器狀態的事實)。
更具體地說 - 如果你是在一個8-CPU機器上運行它,每個帶有一個線程的CPU都是競態的條件消除了?如果將此示例展開爲使用8個線程,則在雙CPU機器上,每個具有4個內核的CPU可能會增加或減少競爭條件? 操作系統如何防止裝配指令的step 3
在兩個不同的CPU上同時運行?
被選爲多CPU和多核之間差異的答案,以及關於在單核上失敗的註釋。甚至沒有考慮過,這是一個很好的觀點。 – 2011-04-03 23:35:50