#define ARM_NEON 1
#if ARM_NEON
#include <arm_neon.h>
#endif // ARM_NEON
#include "stdio.h"
#include <memory.h>
#include <malloc.h>
#include <cstdlib>
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
int compareHist(int srcHist[],int dstHist[],int histsize)
{
int distance = 0;
#if ARM_NEON
for (int i = 0; i < histsize; i+=4)
{
int32x4_t _p1 = vld1q_s32(srcHist);
int32x4_t _p2 = vld1q_s32(dstHist);
int32x4_t _min4 = vminq_s32(_p1, _p2); //4维数组最小值
int32x2_t ss1 = vpadd_s32(vget_low_s32(_min4), vget_high_s32(_min4)); //低位相邻两数相加、高位相邻两数相加
distance +=vget_lane_s32(ss1, 0) + vget_lane_s32(ss1, 1); //拿到第一位与第二位的值。相加
srcHist += 4;
dstHist += 4;
}
#else
for (int i = 0; i < histsize; ++i)
{
distance+= MIN(srcHist[i],dstHist[i]);
}
#endif
printf("%d \n",distance );
return distance;
}
// arm-linux-gnueabihf-g++ add_neon.cpp -mfpu=neon temp
int main()
{
int x1[12] = {1,1,0,0,0,0,0,0,1,1,1,1};
int x2[12] = {2,2,2,2,2,2,2,2,3,3,3,3};
//NEON 应当使用16位地址对齐加速计算,否则可能拖慢计算速度
int *x3;
int *x4;
printf("address%d \n", x3 );
printf("address %d \n", x4);
//16位地址对齐
posix_memalign((void **)&x3, 16, 12 * sizeof(int));
posix_memalign((void **)&x4, 16, 12 * sizeof(int));
printf("address%d \n", x3 );
printf("address %d \n", x4);
memcpy(x3,x1,12*sizeof(int));
memcpy(x4,x2,12*sizeof(int));
//直方图相交
compareHist(x3,x4,12);
//posix_memalign申请的内存由free即可释放
free(x3);
free(x4);
}
输出结果:
感谢下列作者:
https://blog.csdn.net/Windgs_YF/article/details/112629405
GitHub - rogerou/Arm-neon-intrinsics: arm neon 相关文档和指令意义
ncnn