NEON 常用函数讲解
目錄
一、基本的加載存儲(chǔ)操作
? ? ? ??1. vld1q_f32
2.vst1q_f32
?3.vld2q_f32?
?4.vst2q_f32
5.vld3q_f32
6.vst3q_f32
7.vld4q_f32, vst4q_f32
二、特殊操作?
?1.vdupq_n_f32
2.vzipq_f32?
?3.vuzpq_f32
4.vcombine_f32?
5.?vget_low_f32
6. vget_high_f32
7.?vtrnq_f32
8.?vextq_f32
9.vget_lane_f32
10.?vsetq_lane_f32
11.vtbl1_s8
12.vrev16_s8
?三、基本數(shù)據(jù)類型的轉(zhuǎn)換
1.vcvtq_u32_f32
2.vcvtq_s32_f32?
3. vcvtq_f32_s32
4.vcvtq_f32_u32
四、基本比較運(yùn)算
1.vceq_f32??
2.vceqq_f32
3.?vmaxq_f32
4.?vminq_f32
5.vpmax_s8
6.vpmin_s8
五、基本的位運(yùn)算
?1.vclsq_s32
?2.vclzq_s32
3.vcnt_s8
4.vmvn_s8?
5.vqneg_s8?
6. vqshl_s8
六、基本的邏輯運(yùn)算
?七、基本的算術(shù)運(yùn)算
1.vadd_f32
2.vaddq_f32
3.vpadd_f32
3.vmulq_f32
4.?vmlaq_f32
?
5.vmlaq_lane_f32
?
6.vmaxq_f3
?7.vrecpeq_f32
?8.vrsqrteq_f32
令初始數(shù)據(jù)為: float d0[4] = {0.f, 1.f, 2.f, 3.f}; float d1[4] = {4.f, 5.f, 6.f, 7.f}; float d2[4] = {8.f, 9.f, 10.f, 11.f}; float d3[4] = {12.f, 13.f, 14.f, 15.f};
一、基本的加載存儲(chǔ)操作
1. vld1q_f32
float32x4_t q0 = vld1q_f32(d0); // 加載 d0 地址起始的 4 個(gè) float 數(shù)據(jù)到 q02.vst1q_f32
vst1q_f32(d1, q0);// 將 q0 中 4 個(gè) float32,賦值給以 d1 為起始地址的 4 個(gè) float32?3.vld2q_f32?
float d4[8]= {1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f}; float32x4x2_t ret = vld2q_f32 (d4);注意,此時(shí)在寄存器是交錯(cuò)讀取的!
?4.vst2q_f32
vst2q_f32 (d4, ret);注意,由于寄存器是交錯(cuò)存儲(chǔ)的,所以內(nèi)存保持不變!
5.vld3q_f32
float d5[12] = {1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f, 10.f, 11.f, 12.f}; float32x4x3_t f = vld3q_f32 (d5);6.vst3q_f32
vst3q_f32 (d5, f);7.vld4q_f32, vst4q_f32
略?
二、特殊操作?
?1.vdupq_n_f32
float32x4_t res = vdupq_n_f32(0.f); // 存儲(chǔ)的四個(gè) float32 都初始化為 02.vzipq_f32?
float32x4x2_t q4 = vzipq_f32 (q0, q1);?3.vuzpq_f32
float32x4x2_t ret = vuzpq_f32 (q0, q1);?可見,打包 (zip)、拆包(unzip)并不是想當(dāng)然的可逆的運(yùn)算
4.vcombine_f32?
float32x2_t a = vget_low_f32(q0); float32x2_t b = vget_high_f32(q0);float32x4_t ret = vcombine_f32 (a, b);5.?vget_low_f32
float32x2_t low = vget_low_f32(q0); // 取低2位?
6. vget_high_f32
float32x2_t high = vget_high_f32(q0); // 取高2位?
7.?vtrnq_f32
float32x4x2_t ret = vtrnq_f32 (q0, q1)?
8.?vextq_f32
// 拼接兩個(gè)寄存器并返回從第 n 位開始的大小為4的寄存器 0<=n<=3
res = vextq_f32(q0, q1, 2); //取 q1 低2位,拼接到 q0 的高位,保留 q0 的高2位(移到低位)
// q0, q1 實(shí)際數(shù)據(jù)沒(méi)有變化
- ?vext_u8 的例子:
9.vget_lane_f32
float lane0 = vget_lane_f32(ss0, 0);// get 0th parameter in vector?
10.?vsetq_lane_f32
float32x4_t res = vsetq_lane_f32(d1[0], q1, 1);//用 d1[0] 的數(shù)據(jù)替換掉 q1[1](q1 實(shí)際數(shù)據(jù)沒(méi)有變化)11.vtbl1_s8
int8x8_t r = vtbl1_s8 (p, q);12.vrev16_s8
int8x8_t s = vrev16_s8 (q);?
?三、基本數(shù)據(jù)類型的轉(zhuǎn)換
1.vcvtq_u32_f32
uint32x4_t ui0 = vcvtq_u32_f32 (q0);2.vcvtq_s32_f32?
int32x4_t i0 = vcvtq_s32_f32 (q1);3. vcvtq_f32_s32
float32x4_t f0 = vcvtq_f32_s32 (i0);?
4.vcvtq_f32_u32
float32x4_t uf0 = vcvtq_f32_u32 (ui0)四、基本比較運(yùn)算
1.vceq_f32??
uint32x2_t c = vceq_f32 (a, b); // 等于2.vceqq_f32
uint32x4_t q = vceqq_f32 (q1, q2); // 等于?
3.?vmaxq_f32
float32x4_t ret = vmaxq_f32 (q2, q1);4.?vminq_f32
float32x4_t ret0 = vminq_f32 (q2, q1);?
5.vpmax_s8
int8x8_t r = vpmax_s8 (p, q);?
6.vpmin_s8
int8x8_t s = vpmin_s8 (p, q);?
五、基本的位運(yùn)算
?1.vclsq_s32
int32x4_t q1 = vclsq_s32 (q0); // 統(tǒng)計(jì)和符號(hào)位相同的 bit 數(shù)(不包括符號(hào)位)?2.vclzq_s32
int32x4_t q2 = vclzq_s32 (q0); // 統(tǒng)計(jì)前綴 0 的個(gè)數(shù)?
3.vcnt_s8
int8_t d0[8] = {0, 1, 2, 3, 4, 5, 6, 7};
int8x8_t q = vld1_s8(d0);
int8x8_t p = vcnt_s8 (q); // 二進(jìn)制形式的 1 的個(gè)數(shù)
?
4.vmvn_s8?
int8x8_t q = vmvn_s8 (p); // 按位取反??
5.vqneg_s8?
int8x8_t r = vqneg_s8 (p);?
6. vqshl_s8
int8_t d0[8] = {0, 1, 2, 3, 4, 5, 6, 7};
int8_t d1[8] = {1, 1, 2, 2, 3, 3, 4, 4};
int8x8_t p = vld1_s8(d0);
int8x8_t q = vld1_s8(d1);
int8x8_t pq = vqshl_s8 (p, q); // 左移對(duì)應(yīng)的位數(shù)
如果移位是負(fù)數(shù) ,則變成截?cái)嗟挠乙?/p>
int8_t d0[8] = {0, 1, 2, 3, 4, 5, 6, 7};
int8_t d1[8] = {-1, -1, -2, -2, -3, -3, -4, -4};
int8x8_t p = vld1_s8(d0);
int8x8_t q = vld1_s8(d1);
int8x8_t pq = vqshl_s8 (p, q);
?
六、基本的邏輯運(yùn)算
?略
?七、基本的算術(shù)運(yùn)算
1.vadd_f32
float32x2_t ss0 = vadd_f32(vget_low_f32(q2), vget_high_f32(q2));//對(duì)應(yīng)元素相加?
2.vaddq_f32
float32x4_t q4 = vaddq_f32 (q1, q2);?
3.vpadd_f32
float32x2_t ss1 = vpadd_f32(vget_low_f32(q2), vget_high_f32(q2));//相鄰元素相加3.vmulq_f32
float32x4_t res0 = vmulq_f32(q0, q1); //點(diǎn)乘?
4.?vmlaq_f32
float32x4_t res1 = vmlaq_f32(q0, q1, q2);// q0 + q1*q2?
?
5.vmlaq_lane_f32
// ?ri = ai + bi * c[d];
float32x4_t res = vmlaq_lane_f32(q0, q1, vget_low_f32(q2), 0);//取 q2 的第0個(gè)數(shù),分別與 q1 中的 4 個(gè)數(shù)相乘,得到 4 個(gè)結(jié)果與 q0 累加
?
6.vmaxq_f3
float32x4_t max = vmaxq_f32(q1, q2);//對(duì)應(yīng)元素比較,取最大?
?7.vrecpeq_f32
float32x4_t q5 = vrecpeq_f32 (q1); // 倒數(shù)?8.vrsqrteq_f32
float32x4_t q6 = vrsqrteq_f32 (q1); // 倒數(shù)平方根待續(xù)
總結(jié)
以上是生活随笔為你收集整理的NEON 常用函数讲解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 常用的trim函数
- 下一篇: 赛事启动 |香港科大-杰瑞集团 2022