参考:arm NEON简介
快速上手指南
清晰的简介
参考手册
SIMD:一条指令处理多个数据。在32bit内核处理器上,如cortexA系列,如果不采用SIMD将会把大量时间花费在处理8-bit或者16-bit的数据上,但处理器本身的ALU,寄存拿起、数据深度是为了32bit的运算而设计的,因此设计NEON。
NEON:是一种基于SIMD思想的ARM,结合了64bit和128bit的SIMD指令集,提供128bit宽的向量运算,该技术从ARM7开始被采用,目前可在ARM Cortex-A和Cortex-A系列处理器使用。
NEON包含16个128位寄存器,拥有100多条完整指令,并且拥有独立的寄存器系统和独立的硬件执行单元,支持8位、16位、32位、64位等数据类型的向量运算,最多可同时对16路8位数据进行并行计算,可用于2D/3D图形图像加速、音视频编解码、数字信号处理等应用。
参考:
ARM NEON技术在车位识别算法中的应用
这里介绍了NEON的基本使用。
汇编指令:汇编指令集合
这个很有用,方便查阅
这里也有指令的详细解释
OPENCV_HAL_IMPL_NEON_UTILS_SUFFIX(uint8x16, uint8x8, u8)
OPENCV_HAL_IMPL_NEON_UTILS_SUFFIX(int8x16, int8x8, s8)
OPENCV_HAL_IMPL_NEON_UTILS_SUFFIX(uint16x8, uint16x4, u16)
OPENCV_HAL_IMPL_NEON_UTILS_SUFFIX(int16x8, int16x4, s16)
OPENCV_HAL_IMPL_NEON_UTILS_SUFFIX(uint32x4, uint32x2, u32)
OPENCV_HAL_IMPL_NEON_UTILS_SUFFIX(int32x4, int32x2, s32)
OPENCV_HAL_IMPL_NEON_UTILS_SUFFIX(float32x4, float32x2, f32)
OPENCV_HAL_IMPL_NEON_UTILS_SUFFIX_I64(uint64x2, uint64x1, u64)
OPENCV_HAL_IMPL_NEON_UTILS_SUFFIX_I64(int64x2, int64x1, s64)
//add for int array. assumed that count is multiple of 4
#include
// C version
void add_int_c(int* dst, int* src1, int* src2, int count)
{
int i;
for (i = 0; i < count; i++)
dst[i] = src1[i] + src2[i];
}
}
// NEON version
void add_float_neon1(int* dst, int* src1, int* src2, int count)
{
int i;
for (i = 0; i < count; i += 4)
{
int32x4_t in1, in2, out;
in1 = vld1q_s32(src1);
src1 += 4;
in2 = vld1q_s32(src2);
src2 += 4;
out = vaddq_s32(in1, in2);
vst1q_s32(dst, out);
dst += 4;
}
}
代码中的vld1q_s32会被编译器转换成vld1.32 {d0, d1}, [r0]指令,同理vaddq_s32和vst1q_s32被转换成vadd.i32 q0, q0, q0,vst1.32 {d0, d1}, [r0]。
arm_neon.h 中。类似于:
vadd_s8 (int8x8_t __a, int8x8_t __b)
此方法需要注意2点:
1.必须: #include
2.编译时必须加入; -mfloat-abi=softfp -mfpu=neon
B:使用汇编指令:
效率最高. 使用intrinsics没法控制寄存器分配和内存对齐等。
neon矩阵乘法博客
通用矩阵乘法优化
NEON有32个64位寄存器,因而加载所有的输入矩阵元素到16个64-bit寄存器,我们仍然有16个64位寄存器做后续的处理。
D和Q寄存器:多数的NEON指令有两种方法来访问寄存器组:
作为32个双字寄存器,64-bit位宽,命名为d0-d31
作为16个四字寄存器,128-bit位宽,命名为q0-q15
这些寄存器中一个Q寄存器是一对D寄存器的别名,如Q0是d0和d1寄存器对的别名,寄存器中的值可以用两种方式访问。这种实现方式很类似C语言里的union联合的数据结构。对于浮点的矩阵乘法,我们会经常使用Q寄存器的表达方式,因为经常会处理4个32-bit的单精度浮点,这对应于128-bit的Q寄存器。