ARM處理器會預取指令,那麼我們修改PC寄存器時,被預取的指令是否是被直接丟棄了?

因為工作原因開始接觸Android彙編,由於知識欠缺,很多大家覺得是常識的問題我都不懂,望輕拍。另外各位大大能否推薦一些ARM彙編相關的入門書籍呢?


首先說明一下,一般預取技術都是對上層程序員透明的,也就是說,無論這個CPU有沒有指令預取和數據預取,對上層程序員都不存在影響,程序該怎麼寫還是怎麼寫。ARM全陣營有不少處理器型號,有的不支持預取,有的支持預取,有的不僅支持預取而且預取技術還做得比較激進,但是他們對上層程序員來說都是透明的,預取一般由編譯器控制,或者由處理器自己控制,或者是協同控制,也有很少的一些對性能要求極高的場合,會由程序員繞過編譯器手動插入預取指令,這個不在我們討論範圍內。如果你在擔心CPU的預取會不會打亂你的代碼,這個就大可放心。

然後再來說預取的問題。指令預取有很多種情況,比如從L2 cache裡面預取到L1 instruction cache,從L1 instruction cache裡面預取到流水線前端,但是所有的預取技術,無一例外地都可以歸結成這樣的形勢:一個模式匹配器,去尋找指令地址之中可能存在的某種規律,然後根據這個規律去推斷下一次指令地址在哪裡,預取進來。如果你顯式地修改PC(我不確定ARM各版本的指令集是否允許修改PC,你可以回頭查一下指令集手冊確認一下),破壞了這種規律的話,預取的指令是會被丟棄的。

ARM彙編的話,有一本《計算機組成與設計:硬體軟體介面 ARM版》,它的前三章會講ARM指令集,深入淺出,沒有太多基礎的大一學生也能看懂。


贊同泰羅的說法,不管ARM處理器如何預取,對於程序員都是透明的。具體如何實現那是寫RTL的人需要解決的事。大致原因如下(偏硬體)

很多ARM處理器,分為8級的pipeline,前4個stage稱為prefetch即預取,主要負責從各種cache中取指令以及分支預測,後4個stage讓我們稱它為data processing unit DPU即各種數據處理以及load/store。

你所說的修改PC,in-flight的指令被丟棄的情況很常見。當你有跳轉的時候,PC值由offset或者register而定。當你有call和return時PC值也會變化。這個值經過address calculation unit AGU(計算取指地址的)會被存在pipeline register中。另外提一提分支預測,當你有跳轉的時候,分支預測會預測是該跳還是不該跳,只有該跳的時候,你的offset或者你預測的地址才會生效轉變成你的下一個PC。而預測通常發生在prefetch的最後一級,也就是整個CPU的第四級pipeline。而PC值變化時,之前的pipeline肯定已經有指令在裡面了。那麼現在問題來了,CPU是如何讓這一切對於程序員來說透明的呢。這又得分情況討論:

  1. 假設你的跳轉被預測為該跳:那麼新的PC值會傳給處於第一級pipeline的AGU得到新的取指地址,下一條指令就從跳轉到的地方開始取,同時prefetch會生成force signal告訴CPU此時還在prefetch 1到3級pipeline里的指令將被全部廢棄。這種情況我們有四個clock cycle的penalty。
  2. 然後你的指令從prefetch發給了DPU,假設分支預測對了那麼皆大歡喜,就好像什麼也沒發生,但如果錯了的話,在write back或者在retire(通常是最後兩個pipeline stage),會再次生成force signal,這個force signal會將之前包括prefetch的六七個pipeline全部flush。同時DPU向AGU給出正確的跳轉地址。這種情況的penalty更大。

值得一提的是,指令被廢棄的情況不止是PC值發生跳轉的時候,在prefetch的時候,有可能會突然出現interrupt,或者是特殊的debug請求,還有可能出現ECC error或者address alignment fault。這些都可能導致之前的pipeline被flush指令被廢棄。

但這一切你是看不到的,你所看到的結果永遠是修正好的,畢竟你看到的指令執行不是cycle accurate的。

PS:推薦你ARM system-on-chip architecture,網上應該有的下,裡面有介紹ARM assembly的。


修改pc時一定會丟棄預存的指令。還記得一樓大神的一句話,底層程序員和cpu構架師應該相互信任,各司其職,程序員不需要過多糾結於構架師的問題。


pipeline


作為一名大學狗。cs專業的。我可以很負責任的告訴你,是的、丟棄 因為很難避免不是pipeline的cpu。

所以硬體很恨c++ 的 pointer的。

還有linked list。還有 b jump。


預取是說分支預測嗎?修改pc是說條件沒匹配嗎?如果是這樣,那麼cpu會恢復到預取之前的狀態。具體是通過cpu的寄存器重命名實現。


推薦閱讀:

樹莓派 (Raspberry Pi) 的性能如何?
如何讓樹莓派可以被外網訪問?
我還要繼續學習51單片機嗎?----答疑貼
如何評價華為今天發布的麒麟920?會不會又像K3V2那樣名過其實?
怎樣加入一個開源項目?

TAG:程序員 | ARM | ARM架構 | CPU指令集 | ARM指令 |