近期正在往Android平台移植演算法。確切地說,是針對ARM A8 A9 平台進行最佳化。發現不同晶片的浮點能力差別頗大。A9系列明顯強於A8系列,大約有3倍多的提升,應該就是VFP管線化的優勢。不過即使相同核心,不同廠家的晶片也會有不少差別。起初用本人手機,ATRIX,Tegra2處理器,A9雙核。測算了一下,跑浮點演算法速度是我台式機的三分之一。折算為相同頻率的話,已經相差無幾了。PC的演算法直接編譯就可以使用,速度直接達標,DSP時期的什麼浮點轉定點,直接就Pass掉,啥最佳化不用,真是驚歎。不過拿上其他A8板子,驚喜立馬就飛走了,最佳化還是得做的,活省不了。主要可用的就是NEON了。
最佳化NEON時,挑了幾個典型函數,比如向量內積、比例求和、互相干係數,讓人去嘗試看看。一開始按照TI DSP的慣用招數,將運算用一系列NEON內嵌函式去整,發現速度僅提升了10%,搞不下去。我分析了彙編代碼,發現編出來的有很多棧操作,比如關鍵的運算語句就一條,但前後 vstd 和 vldr 有十來條,不慢才怪。網上搜搜,也有類似情況,似乎編譯器對NEON內聯的最佳化較弱,沒法把運算串起來。使出最後一招:嵌入式彙編手工最佳化,看了半天指令集,挑了最簡單的比例求和函數,其實彙編的話,也就對應三條運算語句,就是算上載入和儲存,也就十來句,比起編譯器出來的幾十條省了很多。運行一下,速度提升了5倍。這下有搞頭了,讓工程師把其他幾個也整了,最高有20倍提升。就是編起來有點費勁,半天一個小函數,只能用於最佳化核心費時的部分。
有兩個比較不錯的參考資料:
http://hilbert-space.de/?p=22 RGB轉灰階的最佳化執行個體,裡面展現了函數對應的彙編指令,以及手工彙編的結果,主要是對載入、儲存進行了最佳化。
http://blogs.arm.com/software-enablement/241-coding-for-neon-part-3-matrix-multiplication/ 官方執行個體,矩陣乘法的NEON移植分析與實現。
另外 OpenMAX庫也可以看看。