什么是neon, neon是arm架构下的一个simd的一种方案, 本质上是一些可以用于simd的寄存器
具体参考官方的图:
官方的图说明对于arm开发板, 有16个128bit的寄存器,或者也可以看作是32个64bit的寄存器
列一下常用的neon函数:
加载数据:
float ptr[4]={1,2,3,4};
float32x4_t loaded_data = vld1q_f32(&ptr);
加载某一个数据:
//将prt指针位置存放的数值加载到neon p向量中的最后一个位置上
float32x4_t p = vld1q_lane_f32(ptr,3)
获取向量中某个数据:
//获取neon向量中的第一个数据,data_vector 是neon的向量, 0是向量首位
float a = vgetq_lane_u32(data_vector, 0)
单个数据拓成neon向量,四个值相等:
//得到一个全是0的neon向量
float32x4_t a = vdupq_n_f32(0.0f)
向量对应相加:
//两个neon向量v_0和v_1 对应元素相加
float32x4_t added_reuslt = vaddq_f32(v_0,v1)
向量每一个元素开根号:
float32x4_t b = vsqrtq_f32(a)
对应元素相乘
//对应元素相乘
float32x4_t a =vmulq_f32(v0,v1)
数据写回:
// 当需要写回neon向量的数据到指针buff的时候 , 只要调用set类函数,这样该目标指针下往后四个数(包括自己 就会变为neon向量中的值)
vst1q_f32(neon_v, ptr)
这里留一个问题大家思考一下,假设有一个neon A向量, 其中是存在NaN值的,那么如何将NaN值得位置找出来, 起初我想得是搞一个全NaN的neon向量, 做对比运算, 其实这个想法是错误的,因为NaN值对于任何值做比较,都是不相等的。
因此我找到了一种简单的办法, A向量自己和自己比, 相等的为非NaN,不等的就是NaN
然后要得到NaN的mask(NaN)的位置为全1, 那么就要再做一个取反的操作即可 vmvnq_u32
本次neon 编程的分享到此结束, 还有很多neon的指令,可以查看arm的intrinsic文档