NEON介紹
在移動平台上進行一些復雜算法的開發,一般需要用到指令集來進行加速。NEON 技術是 ARM Cortex™-A 系列處理器的 128 位 SIMD(單指令,多數據)架構擴展,專門針對大規模並行運算設計的,旨在為消費性多媒體應用程序提供靈活、強大的加速功能,從而顯著改善用戶體驗。
其本質上使用的是128位NEON SIMD寄存器,這意味着如果操作32位浮點數,可同時操作4個(變量可定義:float32x4_t);如果操作 16 位整數(short),可同時操作 8 個(變量可定義:int16x8_t);而如果操作 8 位整數,則可同時操作 16 個(變量可定義:int8x16_t)。
ARMv7 NEON 指令集架構具有 16 個 128 位的向量寄存器,命名為 q0~q15。這 16 個寄存器又可以拆分成 32 個 64 位寄存器,命名為 d0~d31。其中qn和d2n,d2n+1是一樣的,故使用匯編編寫代碼時要注意避免產生寄存器覆蓋。如下圖所示:
NEON數據類型
NEON的數據類型如下圖:
neon的數據類型float32x4_t 可以理解為vector< float32 > (4),同理typexN_t即為vector< type>(N)。在NEON編程中,對單個數據的操作可以擴展為對寄存器,也即同一類型元素矢量的操作,因此大大減少了操作次數。
NEON中指令分為正常指令、寬指令、窄指令、飽和指令、長指令這幾類:
正常指令:數據寬度不變
長指令:源操作數寬度相同 結果寬度擴展 L標記
寬指令:源操作數寬度不同 結果寬度對齊 W標記
窄指令:源操作數寬度相同 結果寬度變窄 N標記
飽和指令:結果溢出就是飽和指令 Q標記
NEON官方示例及詳解
通過一個示例來解釋如何利用NEON內置函數來加速實現統計一個數組內的元素之和。
對於長度為N的數組,上述算法的時間復雜度為O(N)。
采用NEON函數進行加速:
上述算法的時間復雜度為O(N/4),原因在於我們每次往寄存器加載4個float值,然后同時相加。相當於原來需要N次加法操作而現在只需要N/4即可。如果使用更多的寄存器,則可以完成更高倍數的加速。
上述用到的幾個NEON指令解釋為:
除以上的操作外,NEON還支持很多的操作,如矢量相減、矢量相乘、矢量乘加、矢量類型轉換等等。
NEON手冊
以下鏈接為NEON內置函數的手冊,當需要用到某些NEON操作時,可以通過手冊查看使用方法。
NEON內置函數詳細手冊