ARM 浮點運算一
時間:2016-12-14作者:華清遠見
很多時候我們要處理的數據,不僅僅是整數和字符串,還有浮點數即小數。在多媒體數據處理方面表現的更多。是不是所有的CPU都支持,浮點運算呢?答案:不是。 我們常常聽到贏浮點和軟浮點,這些到底說的是什么呢?下面我們就來一探究竟吧。在這里我們說的是ARM核浮點運算。 (1)硬浮點(hard-float) 編譯器將代碼直接編譯成硬件浮點協處理器(浮點運算單元FPU)能識別的指令,這些指令在執行的時候ARM核直接把它轉給協處理器執行。FPU 通常有一套額外的寄存器來完成浮點參數傳遞和運算。使用實際的硬件浮點運算單元(FPU)會帶來性能的提升。 (2)軟浮點(soft-float) 編譯器把浮點運算轉成浮點運算的函數調用和庫函數調用,沒有FPU的指令調用,也沒有浮點寄存器的參數傳遞。浮點參數的傳遞也是通過ARM寄存器或者堆棧完成。現在的Linux系統默認編譯選擇使用hard-float,如果系統沒有任何浮點處理器單元,這就會產生非法指令和異常。因而一般的系統鏡像都采用軟浮點以兼容沒有VFP的處理器。 用一句話總結,軟浮點是通過浮點庫去實現浮點運算的,效率低;硬浮點是通過浮點運算單元(FPU)來完成的,效率高。 一、使用浮點庫實現浮點運算(soft-float) 例如:我想實現兩個浮點數相加,代碼如下: 使用GNU ARM編譯器翻譯成的部分匯編代碼如下: 從圖中我們可以知道,默認情況下,編譯器使用的是軟浮點,圖中__aeabi_fadd這個函數是在浮點庫中實現。如果想讓代碼能正常的運行,還需要在連接的時候靜態連接一下浮點庫。 在這里我們以一個完成的案例來說明一下,軟浮點庫的使用方法。 start.S: 使用硬件浮點實現浮點運算(hard-float) 使用硬件浮點的時候,我們需要給編譯器傳遞一些參數,讓編譯器編譯出硬件浮點單元處理器能識別的指令。 (1)-mfpu=name 參數-mfpu就是用來指定要產生那種硬件浮點運算指令,常用的右vfp和neon等。 浮點協處理器指令: ARM10 and ARM9: (2) -mfloat-abi=value -mfloat-abi=soft 使用這個參數時,其將調用軟浮點庫(softfloat lib)來支持對浮點的運算,GCC編譯器已經有這個庫了,一般在libgcc里面。這時根本不會使用任何浮點指令,而是采用常用的指令來模擬浮點運算。但使用的ARM芯片不支持硬浮點時,可以考慮使用這個參數。在使用這個參數時,連接時一般會出現下面的提示: undefined reference to `__aeabi_fdiv' 或者類似的提示,主要因為一般情況下連接器沒有去主動尋找軟浮點庫,這時使用將libgcc庫加入即可。 -mfloat-abi=softfp -mfloat-abi=hard 這兩個參數都用來產生硬浮點指令,至于產生哪里類型的硬浮點指令,需要由 -mfpu=xxx參數來指令。這兩個參數不同的地方是: -mfloat-abi=softfp生成的代碼采用兼容軟浮點調用接口(即使用-mfloat-abi=soft時的調用接口),這樣帶來的好處是:兼容性和靈活性。庫可以采用-mfloat-abi=soft編譯,而關鍵的應用程序可以采用-mfloat-abi=softfp來編譯。特別是在庫由第三方發布的情況下。 -mfloat-abi=hard生成的代碼采用硬浮點(FPU)調用接口。這樣要求所有庫和應用程序必須采用這同一個參數來編譯,否則連接時會出現接口不兼容錯誤。 我們對main.c文件使用硬件浮點重新編譯: 翻譯成的匯編代碼如下: start.s:
發表評論
|