1. 程式人生 > >ARM指令之精髓DMB,DSB,ISB指令

ARM指令之精髓DMB,DSB,ISB指令

4.3.5 組合語言:指令隔離(barrier)指令和儲存器隔離指令

CM3 中的另一股新鮮空氣是一系列的隔離指令(亦可以譯成“屏障”、“路障”,可互換使用——譯者 注)。它們在一些結構比較複雜的儲存器系統中是需要的(典型地用於流水線和寫緩衝——譯者注)。在 這類系統中,如果沒有必要的隔離,會導致系統發生紊亂危象(race condition),(相當於數電中的“競爭 與冒險”——譯者注).

舉例來說,如果可以在執行時更改儲存器的對映關係或者記憶體保護區的設定,(通過寫 MPU 的寄存 器),就必須在更改之後立即補上一條 DSB 指令(資料同步指令)。因為對 MPU 的寫操作很可能會被放 到一個寫緩衝中。寫緩衝是為了提高儲存器的總體訪問效率而設的,但它也有副作用,其中之一,就是 會導致寫記憶體的指令被延遲幾個週期執行,因此對儲存器的設定不能即刻生效,這會導致緊臨著的下一 條指令仍然使用舊的儲存器設定——但程式設計師的本意顯然是使用新的儲存器設定。這種紊亂危象是後患 無窮的,常會破壞未知地址的資料,有時也會產生非法地址訪問 fault。紊亂危象還有其它的表現形式, 後續章節會一一介紹。CM3 提供隔離指令族,就是要消滅這些紊亂危象(在有些講解計算機體系體系結 構的書中,這類紊亂危象也被稱為“儲存器相關”——譯註)。

CM3 中共有3 條隔離指令,如表4.27 所列

表4.27 隔離指令

指令名

功能描述

DMB

資料儲存器隔離。DMB 指令保證: 僅當所有在它前面的儲存器訪問操作

都執行完畢後,才提交(commit)在它後面的儲存器訪問操作。

DSB

資料同步隔離。比 DMB 嚴格: 僅當所有在它前面的儲存器訪問操作

都執行完畢後,才執行在它後面的指令(亦即任何指令都要等待儲存器訪 問操作——譯者注)

ISB

指令同步隔離。最嚴格:它會清洗流水線,以保證所有它前面的指令都執

行完畢之後,才執行它後面的指令。

DMB 在雙口 RAM 以及多核架構的操作中很有用。如果 RAM 的訪問是帶緩衝的,並且寫完之後

馬上讀,就必須讓它“喘口氣”——用 DMB 指令來隔離,以保證緩衝中的資料已經落實到 RAM 中。 DSB 比 DMB 更保險(當然也是有執行代價的),它是寧可錯殺也不漏網——清空了寫緩衝,使得任 何它後面的指令,不管要不要使用先前的儲存器訪問結果,通通等待訪問完成。大蝦們可以在有絕 對信心時使用 DMB,新手還是使用 DSB 比較保險。
同 DMB/DSB 相比,ISB 指令看起來似乎最強悍,但是卻一身都是“愣勁”,不由分說就“動粗”。
不過它還有其它的用場——對於高階底層技巧:“自我更新”(self-mofifying)程式碼,非常有用。舉例 來說,如果某個程式從下一條要執行的指令處更新了自己,但是先前的舊指令已經被預取到流水線 中去了,此時就必須清洗流水線,把舊版本的指令洗出去,再預取新版本的指令。因此,必須在被 更新程式碼段的前面使用 ISB,以保證舊的程式碼從流水線中被清洗出去,不再有機會執行(譯者覺得 這種做法太工於技巧,有點“作秀”,現實程式設計中應該極少會用到,因此讀者不必太鑽它)。