最近工作需要用到neon指令加速模型推理,所以在此记录neon指令的学习过程,一方面加强自己的记忆,另一方面帮助更多像我一样的小白早日实现财务自由。
好了,neon指令的基本概念我就不多阐述了,直接上代码:
c代码,主要实现这样一个简单的功能:
void first_example_c(unsigned char *src, unsigned char *dst, int size, unsigned char factor)
{
for (int i = 0; i < size; i++)
{
dst[i] = src[i] * factor;
}
}
下面是使用neon指令实现的及具体步骤:
#include<arm_neon.h>
#include<stdio.h>
void first_example_neon(unsigned char *src, unsigned char *dst, int size, unsigned char factor)
{
int main_loop = size / 8; //一个循环处理8个数据,则需要 size / 8个循环
uint8x8_t factor_vct = vdup_n_u8(factor); //将系数factor装载入neon寄存器
for (int i = 0; i < main_loop; i++)
{
uint8x8_t src_vct = vld1_u8(src); //将源数据装载入neon寄存器
uint8x8_t dst_vct = vmul_u8(src_vct, factor_vct); //执行乘法操作,且将结果放入dst_vct寄存器中
vst1_u8(dst, dst_vct); //将dst_vct寄存器中的结果放回内存中
src += 8, dst += 8; //改变地址,指向下个循环要处理的数据。
}
int aa = size - main_loop * 8; //考虑到size不能被8整除的情况
for (int j = 0; j < aa; j++)
{
*dst = *src*factor;
dst++;
src++;
}
}
void main()
{
unsigned char a[9] = { 1,2,3,4,5,6,7,8,9 };
unsigned char b[9];
int size = 9;
unsigned char factor = 2;
first_example_neon(a, b, size, factor);
for (int i = 0; i < 9; i++)
{
printf("%d\n", b[i]);
}
}
这里面用到了:uint8x8_t、vdup_n_u8、vld1_u8、vmul_u8和vst1_u8这几个neon指令。
- uint8x8_t
表示寄存器的数据类型,第一个数字代表的是数据类型的宽度有8/16/32/64,这里数据宽度为8,第二个数字代表一个寄存器中该类型数据的数量,这里也是8。所以uint8x8_t表示8位无符号数的寄存器中共有8个数据。 - vdup_n_u8
对向量进行复制,用于初始化,uint8x8_t factor_vct = vdup_n_u8(factor)表示将寄存器factor_vct存储的8个unsigned char都初始化为factor,如果factor=2,则factor_vct=[2,2,2,2,2,2,2,2]。 - vld1_u8
将数据载入到寄存器中,uint8x8_t src_vct = vld1_u8(src),表示从src中取8个数据(为什么是8个?因为uint8x8类型的寄存器只能存8个数据)到寄存器src_vct中。 - vmul_u8
向量相乘 - vst1_u8
将寄存器中的数据放回内存中。
附加:
基本数据类型:
64 位
int8x8_t, int16x4_t, int32x2_t, int64x1_t,
uint8x8_t, uint16x4_t, uint32x2_t, uint64x1_t,
float32x2_t, float64x1_t(少见)
128 位
int8x16_t, int16x8_t, int32x4_t, int64_2_t,
uint8x16_t, uint16_8_t, uint32x4_t, uint64x4_t,
float32x4_t
另外放一些网址用于neon学习:
1.neon指令查询:https://developer.arm.com/architectures/instruction-sets/intrinsics/#q=vextq_f32
2.一些指令参考:https://blog.csdn.net/weixin_41965270/article/details/89248540
3.一些简单的实例:https://www.jianshu.com/p/70601b36540f
网友评论