2012-06-17 21 views
4

我正在使用本機代碼在Android中進行一些圖像壓縮。由於各種原因,我無法使用預建庫。加速浮點運算(Android ARMv6)

我使用android-ndk-profiler描述了我的代碼,發現瓶頸是 - 令人驚訝的是 - 浮點運算!這裏的配置文件輸出:

Flat profile: 

Each sample counts as 0.01 seconds. 
    % cumulative self    self  total   
time seconds seconds calls ms/call ms/call name  
40.37  0.44  0.44        __addsf3 
11.93  0.57  0.13  7200  0.02  0.03 EncodeBlock 
    6.42  0.64  0.07 535001  0.00  0.00 BitsOut 
    6.42  0.71  0.07        __aeabi_fdiv 
    6.42  0.78  0.07        __gnu_mcount_nc 
    5.50  0.84  0.06        __aeabi_fmul 
    5.50  0.90  0.06        __floatdisf 
    ... 

我GOOGLE了__addsf3,顯然它是一個軟件浮點運算。呸。我對ARMv6架構內核做了更多的研究,除非我錯過了一些東西,它沒有硬件浮點支持。那麼,我可以在這裏做些什麼來加快速度?固定點?我知道這通常是用整數完成的,但我不確定如何將我的代碼轉換爲這樣做。有沒有我可以設置的編譯器標誌,因此它會這樣做?歡迎其他建議。

回答

8

當然,你只能用整數算術做任何事情(畢竟你現在正在做的是程序),但是如果它能做得更快或者不能完全取決於你想要做什麼。

浮點是一種通用的解決方案,你可以申請在大多數情況下,只是忘了它,但它是有點罕見的,你的問題真的需要數字廣泛地從令人難以置信的小到令人難以置信的大,52比特的尾數準確性。假設你的計算是關於具有雙精度浮點數的圖形,那麼你可以遠遠小於子原子尺度,遠遠超過宇宙的尺寸......是否真的需要這個範圍?提供的準確度當然取決於FP的規模,但您真正需要的準確度是多少?

你的「內循環」中使用了什麼數字?不知道如果計算速度可以提高很多,很難說。幾乎可以肯定它可以做得更快(FP是一種通用的盲解決方案),但是你可能希望得到的收益有很大的不同。我不知道具體的實現,但我期望它是相當高效的(對於一般情況)。

您應該瞄準更高的邏輯優化級別。

對於基於DCT或小波變換的圖像壓縮(de)壓縮,我認爲實際上不需要浮點算術:您可以考慮精確的縮放數量,並使用整數算術。此外,由於生產近似結果的能力,您可能還擁有額外的自由度。

2

見6502的出色答卷第一...

大多數處理器不必須的FPU,因爲他們不需要。當他們出於某種原因,他們嘗試符合同樣不必要的IEEE754時,那些需要任何這種情況的案例都非常少見。 fpu只是一個整數,有一些東西來跟蹤浮點數,所有這些都可以自己完成。

怎麼樣?讓我們認爲小數和美元,我們可以想到110.50美元,並增加0.07美元,並獲得110.57美元,或者你可以做一切便士11050 + 7 = 11057,然後當你打印它爲用戶在正確的地方放一個點。這就是fpu所做的一切,這就是你需要做的。此鏈接可能會提供或不提供一些洞察http://www.divms.uiowa.edu/~jones/bcd/divide.html

不要覆蓋所有ARMv6處理器的方式,這不是ARM如何分類。有些內核可以選擇FPU,或者在您從ARM購買等產品後自行添加一個內核。例如,ARM11是帶有fpu選項的ARMv6。

另外,僅僅因爲你可以自己跟蹤小數點,如果硬件fpu有可能比固定點自己做得更快。同樣,可能也很容易不知道如何使用fpu並獲得不好的結果,只是讓它們更快。很容易寫不好的浮點代碼。無論您使用固定還是浮動,您都需要跟蹤數字的範圍,並從該控件中移動點,以將整數運算保留在尾數內的核心位置。這意味着要有效地使用浮點數,你應該考慮整數數學在做什麼。一個非常常見的錯誤就是認爲乘數會讓你的精確度變差,而實際上加減法會最大限度地傷害你。