2

x86指令lfence/sfence/mfence用於實現Linux內核中的rmb()/ wmb()/ mb()機制。很容易理解這些用於序列化內存訪問。然而,在編寫代碼時確定何時何地使用這些代碼更困難 - 在遇到運行時行爲中的錯誤之前。確定使用障礙的位置(fence)

我很想知道是否有已知的警告,可以在編寫/審查代碼時檢查,這可以幫助我們確定必須插入障礙的位置。我知道這太複雜了,但是有沒有經驗法則或清單可以幫助我們確定需要這些代碼的地方?

+0

內存屏障不*串行化CPU上的指令,它們串行化CPU外部的內存訪問*。爲了回答你的問題,有必要粘貼整個[文檔](http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux/kernel/git/torvalds/linux.git/tree/Documentation/memory-barriers。文本)。 –

回答

4

我的經驗(不是在Linux內核中)是兩種模式涵蓋絕大多數圍欄需求。

模式「發送/接收」:線程1發送數據到線程2,並且有一個內存位置以某種方式表示「數據已準備就緒」。線程1在數據存儲和商店之間至少需要一個「數據準備就緒」的保護。線程2在「數據已準備就緒」的數據負載和數據負載之間需要一個界限。

如果在傳輸中只涉及常規(非非暫時性,DMA設備等)加載/存儲,則只需要編譯器防護。此外,LOCK前綴說明暗示了柵欄。例如,「數據已準備就緒」的位置有時不僅僅是一個標誌,而是一個原子計數器,並且用於操縱它的LOCK加前綴的增量/減量可以用作柵欄。

此模式還涵蓋自旋鎖。釋放鎖定是「發送」。獲取鎖是「收到

模式。」 共識「:。兩個線程必須到達的東西共識必須有(由LOCK前綴的指令或暗示或一個)的MFENCE柵欄必須之間「我發表了我的投票」和「我讀了其他主題的投票」Dekker's protocol就是一個例子,困難的部分是發現這種模式,我們曾經錯過了TBB內部的一個共識問題是「有例外?「最終我們意識到這是一個共識問題,因此需要一個保護。

以上兩種模式是不包括所有情況的經驗法則,但是我發現它們覆蓋了99%的案例