linux kernel浮點處理

目前大多數CPU都支持浮點運算單元FPU,FPU作爲一個單獨的協處理器放置在處理器核外,但是對於嵌入式處理器,浮點運算本來就少用,有些嵌入式處理器就會去掉浮點協處理器。X86處理器一般都是有FPU的。而ARM PPC MIPS處理器就會出現沒有FPU的現象。linux kernel如何處理浮點運算,我們就分爲帶FPU的處理器和不帶FPU的處理器來討論。

一 對於帶FPU的處理器

1 對於linux kernel來說,kernel本身編譯默認使用了-msoft-float選項,默認編譯爲軟浮點程序,軟浮點含義是有gcc編譯器模擬浮點運算(glibc庫提供),將浮點運算代碼替換爲定點運算。對於帶FPU的處理器,我們可以將編譯選項-msoft-float去掉,一般是在arch/xxx/Makefile中。將kernel編譯爲硬浮點,也就是讓處理器的浮點指令計算浮點,硬浮點運算肯定要比模擬的定點運算效率高。(kernel代碼中一般不會有浮點運算,所以效率影響不大)

2 對於運行在kernel上的app來說,特別是對於圖形程序,如QT,浮點運算較多,我們直接編譯即可,因爲處理器支持浮點運算,支持浮點運算指令。

二 對於不帶FPU處理器

1 對於linux kernel來說,編譯默認使用了-msoft-float選項,默認編譯爲軟浮點程序,linux kernel編譯不依賴鏈接任何庫,kernel中來實現對應的模擬浮點ABI。

2 對於運行在kernel之上的app來說,如何處理浮點運算,這裏就有2種方法了:

(1) 由kernel來模擬軟浮點

應用程序使用硬浮點直接編譯(編譯器默認就是編譯成硬浮點程序)。而對於kernel,我所瞭解的PPC MIPS處理器都有專門的浮點運算異常處理,程序運行碰到浮點指令,無法運行浮點指令時,硬件會產生相應的中斷異常,kernel浮點異常處理程序根據指令內容進行軟浮點模擬操作,將運算結果返回之後再恢復到用戶空間執行。對於ARM我在其異常介紹中沒有找到對於浮點計算的異常入口,但是kernel中也有對於其軟浮點的支持,在配置ARM Linux內核時,應該都會看到這樣的配置:

menu "Floating point emulation"

comment "At least one emulation must be selected"

config FPE_NWFPE

...

具體ARM如何實現支持異常模擬軟浮點,具體實現有時間還需要仔細看代碼,在arch/arm/nwfpe中。這樣的方式好處在於應用程序不需要重新編譯,需要在kernel中把浮點模擬打開即可,使用起來非常方便。但是缺點也很明顯,每次浮點操作都要觸發中斷異常,用戶空間和內核空間切換,執行效率太低。

(2)使用軟浮點重新編譯app

這樣可以避免上述問題,app編譯時需要連接glibc庫的,使用--msoft-float,使用glibc的模擬浮點,替換爲定點運算,這樣的好處是運行性能上會好一些。但缺點是因爲使用了不同的編譯選項,使用的ABI可能就發生了變化,如果某個庫或者應用沒有使用同樣的編譯選項(ABI不同),系統運行時會出現意想不到的情況,甚至造成崩潰。

根據最近對PPC一款處理器的調試記錄,kernel正常啓動進入console後死在某一地址,用戶空間浮點運算多,詢問IC後得知FPU去掉,而處理器浮點異常沒有使能。這樣遇到浮點指令,處理器不會觸發異常,也不知道該如何運行該指令。所以進行kernel移植時對於處理器有無FPU也要搞清楚,如果處理器去掉了FPU,而核沒有做相應的處理(使能浮點異常),那麼APP的浮點指令運行結果就是無法預測的,這時可以採用軟浮點工具鏈來編譯APP。

這裏有一點思考:
對於一款處理器,處理器設計中有浮點異常(MIPS PPC都是),其外也可以接FPU。
在接FPU後,處理器核內就要屏蔽掉浮點異常,不然浮點運算還是產生浮點異常,FPU就沒有實用意義了。
無FPU,則處理器核內要使能浮點異常,不然就跟我上面遇到的問題一樣,處理器不知道該如何運行該浮點指令,結果就無法預測了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章