說一個內核中的線程正在旋轉一個變量,該變量將由運行在另一個內核上的線程更新。我的問題是什麼是在緩存級別的開銷。請等待的線程緩存變量,並因此不會導致總線上的任何流量,直到寫入線程寫入該變量?高速緩存一致性方面的自旋循環開銷
如何減少這種開銷。 x86 pause
指令有幫助嗎?
說一個內核中的線程正在旋轉一個變量,該變量將由運行在另一個內核上的線程更新。我的問題是什麼是在緩存級別的開銷。請等待的線程緩存變量,並因此不會導致總線上的任何流量,直到寫入線程寫入該變量?高速緩存一致性方面的自旋循環開銷
如何減少這種開銷。 x86 pause
指令有幫助嗎?
我相信所有現代x86 CPU都使用MESI protocol。因此,旋轉的「讀取器」線程可能會以「獨佔」或「共享」模式緩存數據副本,在旋轉時不會產生內存總線流量。
只有當另一個內核寫入該位置時,它纔會執行跨核心通信。
[更新]
A「自旋鎖」像這僅僅是一個好主意,如果你不會被旋轉很長時間。如果在變量更新之前可能需要一段時間,請改用互斥鎖+條件變量,這會讓線程進入睡眠狀態,以便在等待時不會增加開銷。
(順便說一句,我懷疑很多人 - 包括我在內 - 想知道「什麼是你真正想要做什麼?」)
如果你短時間旋轉鎖定,你通常會很好。然而,在Linux上有一個計時器中斷(我假設其他操作系統類似),所以如果你鎖定10毫秒或接近它,你會看到緩存干擾。
我聽說有可能修改Linux內核以防止特定內核中的所有中斷,並且這種干擾消失,但我不知道這是幹什麼的。
我認爲RHEL 5允許通過命令行應用程序[IRQ綁定](http://rt.et.redhat.com/wiki/index.php?title=RHEL-RT_AffinityHowto&printable=yes#IRQ_.28interrupt.29_binding)。 –
確實如此,但「本地計時器中斷」無法移動,因爲它每秒至少中斷100次線程。 (它可以配置得更高)如果你知道如何關閉它,我會非常感興趣。 ;) –
在兩個線程的開銷的情況下,可以忽略不計了,反正它做一個簡單的基準可能是一個好主意。例如,如果您實施螺旋鎖,線程花費多少時間進入旋轉。 這個效果在緩存上叫做緩存線彈跳。
我在this post中對此進行了廣泛的測試。一般的開銷是由自旋鎖的總線鎖定組件引起的,通常是指令「xchg reg,mem」或它的一些變體。由於無法避免特定的開銷,因此您可以選擇節省調用自旋鎖的頻率,並在釋放鎖之前執行絕對最低的工作量(一旦鎖定到位)。
我假設你指的是SMP? –
是的Eli,我指的是SMP系統。 – MetallicPriest