Neon指令集优化快速入门教程
程序员文章站
2022-03-07 13:09:12
...
文章目录
1. Neon是什么?
Neon是一个商标名称,指的是Arm对Advanced SIMD Architecture的实现。SIMD代表单指令多数据。由于SIMD指令比等效的SISD(单指令单数据)指令可执行更多的操作,因此使用SIMD指令的程序平均每条指令可以处理更多数据。
2.Neon为什么速度快
原因有以下几条:
Neon有32个128bit寄存器,
- 能够输入多行的数据同时操作。
- Neon基于SIMD,一条指令操作多个数据,对多个数据项同时执行相同的操作。这些数据项在较大的寄存器中打包为单独的通道。
- CPU运算比加载数据快,速度瓶颈在加载数据这里。
- 可以操作多种数据类型,包括浮点数
- 基于位和字节向量操作,避免了拆解字节的耗费。
主要用途:
为了加速音频视频编解码,2D/3D图形和游戏
3. Neon基础概念
4. Neon的C语言接口
C语言程序中集成Neon的方法有哪些
使用Neon内联函数 arm_neon.h
使用Neon汇编指令
Neon 内联函数 参考手册哪里找
链接:https://developer.arm.com/architectures/instruction-sets/simd-isas/neon/intrinsics
如何在C中使用Neon示例?
示例:把RGB 交织排列的数组解交织?
单纯用C来实现
for (int i=0; i < len_color; i++) {
r[i] = rgb[3*i];
g[i] = rgb[3*i+1];
b[i] = rgb[3*i+2];
}
如果用Neon来实现
int num8x16 = len_color / 16;
uint8x16x3_t intlv_rgb;
for (int i=0; i < num8x16; i++) {
intlv_rgb = vld3q_u8(rgb+3*16*i);
vst1q_u8(r+16*i, intlv_rgb.val[0]);
vst1q_u8(g+16*i, intlv_rgb.val[1]);
vst1q_u8(b+16*i, intlv_rgb.val[2]);
}
其中:
uint8x16_t : 表示长度为16的unsigned int 8bit 的数组 寄存器。
uint8x16x3_t: 包含三个 uint8x16_t的结构
vld3q_u8(): 输入一个连续的3x16[…]的数组,把他们加载到三个通道中,返回一个 uint8x16x3_t 结构。
Neon的C语言接口中变量的命名规律
变量命名方式:
baseWxLxN_t
base 是基础数据类型,
W是基础类型的宽度,
L 是向量的长度,
N是向量数组的个数
函数命名方式:
ret v[p][q][r]name[u][n][q](args)
ret:返回值类型
v:表示vector
r : 圆整操作
name:SIMD指令名称
u:unsigned, n: narrow, q:做后缀表示128位运算 quarter*32;
5. Android Studio中配置Neon环境
很简单
Android studio 新建C++项目,包括NDK
在build.gradle (Module: app) 文件中添加:
defaultConfig {
ndk.abiFilters 'x86', 'armeabi-v7a', 'arm64-v8a'
externalNativeBuild {
cmake {
cppFlags ""
arguments "-DANDROID_ARM_NEON=ON"
}
}
}
最后在需要的C程序文件中导入#include <arm_neon.h>
6. 运算和缓存
7.名词解释
SIMD 单指令多数据结构(Single Instruction Multiple Data)
下一篇: Postgresql部署及简单操作