ARM

2013-03-19 28 views
17

中的屏障(DSB,DMB,ISB)的實際使用情況我瞭解,DSB,DMB和ISB是防止重新排序指令的障礙。 我也可以爲他們每個人找到很多非常好的解釋,但很難想象我必須使用它們的情況。ARM

另外,從開源代碼中,我時常看到這些障礙,但很難理解它們爲什麼被使用。只是一個例子,在Linux內核3.7 tcp_rcv_synsent_state_process功能,有一個線如下:

if (unlikely(po->origdev)) 
      sll->sll_ifindex = orig_dev->ifindex; 
    else 
      sll->sll_ifindex = dev->ifindex; 

    smp_mb(); 

    if (po->tp_version <= TPACKET_V2) 
      __packet_set_status(po, h.raw, status); 

其中smp_mb()基本上是DMB。 你能否給我一些真實的例子?這將有助於更多地瞭解障礙。

+0

這個問題是一個最近的例子:http://stackoverflow.com/q/15003405/1163019 – auselen 2013-03-19 07:17:17

+0

Cortex程序員指南也有一個障礙(11.2)的部分。 http://infocenter.arm.com/help/topic/com.arm.doc.den0013c/index.html – auselen 2013-03-19 07:21:43

+1

我仍然投票結束,因爲這是一個非常廣泛的問題。 – auselen 2013-03-19 07:22:01

回答

26

對不起,不會給你一個像你問的直截了當的例子,因爲你已經在瀏覽Linux源代碼,你有很多這樣的東西要去,而且它們看起來並不像幫幫我。不要羞愧 - 每個理智的人至少最初都會被內存訪問順序問題困惑:)

如果你主要是一個應用程序開發人員,那麼你就不必擔心太多 - 無論您使用的併發框架將爲您解決它。

如果您主要是設備驅動程序開發人員,那麼可以非常直觀地找到示例 - 只要您的代碼在先前的訪問已產生效果(清除中斷源,寫入DMA描述符)之前存在對某些代碼的依賴關係執行其他訪問(重新啓用中斷,啓動DMA事務)。

如果您正在開發併發框架(或調試一個)的過程中,您可能需要更多地閱讀該主題 - 但是您的問題表明一種表面好奇而不是直接需要? 如果您正在開發自己的線程之間傳遞數據的方法,而不是基於併發框架提供的基元,那是爲了所有意圖和目的的一個併發框架。Memory Barriers: a Hardware View for Software Hackers

如果這是一個有點太鐵桿,我寫了一個3部分組成的系列博客說的有點:

保羅·麥肯尼就需要記憶障礙,產生什麼影響,他們實際上在處理器寫一篇優秀的論文更輕量級,並完成與ARM特定的視圖。第一部分是Memory access ordering - an introduction

但是,如果它是特定的例子列表,特別是對於ARM架構,你可能會做得比Barrier Litmus Tests and Cookbook差很多。

額外的,額外的光線程序員的看法,而不是完全正確的體系結構的版本是:

  • DMB - 每當一個內存訪問需要與問候到另一個存儲訪問排序。
  • DSB - 只要在程序執行前需要完成存儲器訪問。
  • ISB - 每當指令讀取需要在程序中的某個點之後明確發生時,例如在存儲器映射更新之後或寫入要執行的代碼之後。 (實際上,這意味着「在這一點上扔掉任何預取指令」)。
4

通常情況下,如果您必須確保內存訪問按特定順序進行,您需要使用內存屏障。出於多種原因,這可能是必需的,當兩個或更多進程/線程或硬件組件訪問相同的內存結構(通常需要保持一致)時,這通常是必需的。

它經常用於DMA傳輸。一個簡單DMA控制結構可能是這樣的:

struct dma_control { 
    u32 owner; 
    void * data; 
    u32 len; 
}; 

所有者通常會被設置爲類似OWNER_CPU或OWNER_HARDWARE,以表示兩個參與者誰被允許與結構的工作。這改變了這種

代碼通常會喜歡這樣

dma->data = data; 
dma->len = length; 
smp_mb(); 
dma->owner = OWNER_HARDWARE; 

因此,數據的LEN總是所有權之前設置被轉移到DMA硬件。否則,引擎可能會得到陳舊的數據,如未更新的指針或長度,因爲CPU會重新排序內存訪問。

對於在不同內核上運行的進程或線程也是如此。可以用類似的方式進行交流。

2

障礙要求的一個簡單示例是自旋鎖。如果您使用比較和交換(或ARM上的LDREX/STREX)並且沒有障礙來實現自旋鎖,則允許處理器推測性地從存儲器加載值,並且將計算值懶散地存儲到存儲器,並且這些均不需要發生按照指令流中的加載/存儲的順序。

DMB尤其阻止了DMB周圍的內存訪問重新排序。如果沒有DMB,處理器可能會在螺旋鎖釋放後將商店重新排列到受自旋鎖保護的內存中。或者,處理器可以在自旋鎖實際被鎖定之前讀取由自旋鎖保護的內存,或者在被不同的上下文鎖定時。

unixsmurf已經指出,但我也會指出你Barrier Litmus Tests and Cookbook。它有一些很好的例子說明你應該在哪裏以及爲什麼要使用障礙。