ARM NEON常用函式總結

2021-08-28 09:02:56 字數 2634 閱讀 5988

neon 技術是 arm cortex™-a 系列處理器的 128 位 simd(單指令,多資料)架構擴充套件,旨在為消費性多**應用程式提供靈活、強大的加速功能,從而顯著改善使用者體驗。它具有 32 個暫存器,64 位寬(雙倍檢視為 16 個暫存器,128 位寬。)

目前主流的iphone手機和大部分android手機都支援arm neon加速,因此在編寫移動端演算法時,可利用neon技術進行演算法加速,以長度為4的暫存器大小為例,相應的提速倍數約是原始的4倍。

neon 指令可執行「打包的 simd」處理:

暫存器被視為同一資料型別的元素的向量 

資料型別可為:簽名/未簽名的 8 位、16 位、32 位、64 位單精度浮點

指令在所有通道中執行同一操作

如下圖所示:

本文主要介紹float32x4_t相關的結構及函式,

float32x4_t 可以理解為vector (4),同理typexn_t即為vector(n)。

在neon程式設計中,對單個資料的操作可以擴充套件為對暫存器,也即同一型別元素向量的操作,因此大大減少了操作次數。

這裡以乙個小例子來解釋如何利用neon內建函式來加速實現統計乙個陣列內的元素之和。

以c++**為例:

原始演算法**如下:

#include using namespace std; 

float sum_array(float *arr, int len)

float sum(0.0);

for(int i=0; i對於長度為n的陣列,上述演算法的時間複雜度時o(n)。

採用neon函式進行加速:

#include #include //需包含的標頭檔案

using namespace std;

float sum_array(float *arr, int len)

int dim4 = len >> 2; // 陣列長度除4整數

int left4 = len & 3; // 陣列長度除4餘數

float32x4_t sum_vec = vdupq_n_f32(0.0);//定義用於暫存累加結果的暫存器且初始化為0

for (; dim4>0; dim4--, arr+=4) //每次同時訪問4個陣列元素

float sum = vgetq_lane_f32(sum_vec, 0)+vgetq_lane_f32(sum_vec, 1)+vgetq_lane_f32(sum_vec, 2)+vgetq_lane_f32(sum_vec, 3);//將累加結果暫存器中的所有元素相加得到最終累加值

for (; left4>0; left4--, arr++)

sum += (*arr) ; //對於剩下的少於4的數字,依次計算累加即可

return sum;

}

上述演算法的時間複雜度時o(n/4)

從上面的例子看出,使用neon函式很簡單,只需要將依次處理,變為批處理(如上面的每次處理4個)。

上面用到的函式有:

float32x4_t vdupq_n_f32 (float32_t value)

將value複製4分存到返回的暫存器中

float32x4_t vld1q_f32 (float32_t const * ptr)

從陣列中依次load4個元素存到暫存器中

相應的 有void vst1q_f32 (float32_t * ptr, float32x4_t val)

將暫存器中的值寫入陣列中

float32x4_t vaddq_f32 (float32x4_t a, float32x4_t b)

返回兩個暫存器對應元素之和 r = a+b

相應的 有float32x4_t vsubq_f32 (float32x4_t a, float32x4_t b)

返回兩個暫存器對應元素之差 r = a-b

float32_t vgetq_lane_f32 (float32x4_t v, const int lane)

返回暫存器某一lane的值

其他常用的函式還有:

float32x4_t vmulq_f32 (float32x4_t a, float32x4_t b)

返回兩個暫存器對應元素之積 r = a*b

float32x4_t vmlaq_f32 (float32x4_t a, float32x4_t b, float32x4_t c)

r = a +b*c

float32x4_t vextq_f32 (float32x4_t a, float32x4_t b, const int n)

拼接兩個暫存器並返回從第n位開始的大小為4的暫存器 0<=n<=3

例如a: 1 2 3 4

b: 5 6 7 8

vextq_f32(a,b,1) -> r: 2 3 4 5

vextq_f32(a,b,2) -> r: 3 4 5 6

vextq_f32(a,b,3) -> r: 4 5 6 7

其他常用的函式可以參考開發**

總之,neon學習入門很快,但如果想要更精深,就需要多花些時間和功夫在上面。

ARM neon常用四類指令

neon常用指令分四類 算術 邏輯 比較 資料搬移。助記符 含義 add 加法 算術運算 sub 減法 mul 乘法 mla 乘加 mls 乘減 abd 兩個向量相減之後的絕對值 ceq 比較 比較運算 cge 比較 cle 比較 cgt 比較 clt 比較 max 最大值 min 最小值 shl ...

常用函式總結

includeunsigned long int htonl unsigned long int hostlong unsigned short int htons unsigned short int hostshort unsigned long int ntohl unsigned long ...

常用函式總結

isset 檢查變數是否設定 unset 銷毀變數 var dump 列印變數的詳細資訊 echo 輸出乙個或多個字串 print 輸出字串 printf 輸出格式化字串 sprintf return a formatted string print r 列印關於變數的易於解釋的資訊 d efine...