arm 饱和指令_ARM aarch64汇编学习笔记(九):使用Neon指令(一)
NEON是一种基于SIMD思想的ARM技术。 SIMD, Single Instruction Multiple Data,是一种单条指令处理多个数据的并行处理技术,相比于一条指令处理一个数据,运算速度将会大大提高。
ARMv8 有31 个64位寄存器,1个不同名字的特殊寄存器,用途取决于上下文, 因此我们可以看成 31个64位的X寄存器或者31个32位的W寄存器(X寄存器的低32位)
ARMv8有32个128位的V寄存器,相似的,我们同样可以看成是32个32位的S寄存器或者32个64位的D寄存器。
也可以用作32个64bit D0-D31或32个32bit S0-S31 或32个 16bit H0-h31 或 32个8bit B0-B31。
以一个简单的例子来说明使用Neon带来的收益。
比如, 现在有一个很简单的需求, 有2组数据, 每组数据有16 x 1024个整型数, 让它们按顺序一一相加,得到相加的和(每组数据的数不超过255,相加的和如果大于255,则返回255).
如果用C语言实现:#include
#include
#define MAX_LEN 16 * 1024 * 1024
typedef unsigned char uint_8t;
typedef unsigned short uint_16t;
int main()
{
double start_time;
double end_time;
uint_8t *dist1 = (uint_8t *)malloc(sizeof(uint_8t) * MAX_LEN);
uint_8t *dist2 = (uint_8t *)malloc(sizeof(uint_8t) * MAX_LEN);
uint_16t *ref_out = (uint_16t *)malloc(sizeof(uint_16t) * MAX_LEN);
// 2组数据随机赋值
for (int i = 0; i < MAX_LEN; i++)
{
dist1[i] = rand() % 256;
dist2[i] = rand() % 256;
}
start_time = clock();
for (int i = 0; i < MAX_LEN; i++)
{
ref_out[i] = dist1[i] + dist2[i];
if (ref_out[i] > 255)
{
ref_out[i] = 255;
}
}
end_time = clock();
printf("C use time %f s\n", end_time - start_time);
return 0;
}
因为C语言的实现每次相加都只操作了一个寄存器,由于每一个输入和输出都不大于255, 可以用8bit的寄存器保存,对于寄存器而言造成了浪费。
如果使用Neon进行加速:.text
.global asm_add_neon
asm_add_neon:
LOOP:
LDR Q0, [X0], #0x10
LDR Q1, [X1], #0x10
UQADD V0.16B, V0.16B, V1.16B
STR Q0, [X2], #0x10
SUBS X3, X3, #0x10
B.NE LOOP
RET
Q0代表数组A, Q1代表数组B, 每次读128bit (16个), 利用ARM vector无饱和相加指令UQADD进行计算,得到的结果存储在X2寄存器。
比较C语言和ARM NEON加速后实现的性能:#include
#include
#define MAX_LEN 16 * 1024 * 1024
typedef unsigned char uint_8t;
typedef unsigned short uint_16t;
extern int asm_add_neon(uint_8t *dist1, uint_8t *dist2, uint_8t *out, int len);
int main()
{
double start_time;
double end_time;
uint_8t *dist1 = (uint_8t *)malloc(sizeof(uint_8t) * MAX_LEN);
uint_8t *dist2 = (uint_8t *)malloc(sizeof(uint_8t) * MAX_LEN);
uint_8t *out = (uint_8t *)malloc(sizeof(uint_8t) * MAX_LEN);
uint_16t *ref_out = (uint_16t *)malloc(sizeof(uint_16t) * MAX_LEN);
for (int i = 0; i < MAX_LEN; i++)
{
dist1[i] = rand() % 256;
dist2[i] = rand() % 256;
}
start_time = clock();
for (int i = 0; i < MAX_LEN; i++)
{
ref_out[i] = dist1[i] + dist2[i];
if (ref_out[i] > 255)
{
ref_out[i] = 255;
}
//printf("%d dist1[%d] dist2[%d] refout[%d] \n", i,dist1[i], dist2[i], ref_out[i]);
}
end_time = clock();
printf("C use time %f s\n", end_time - start_time);
start_time = clock();
asm_add_neon(dist1, dist2, out, MAX_LEN);
end_time = clock();
printf("asm use time %f s\n", end_time - start_time);
for (int i = 0; i < MAX_LEN; i++)
{
if (out[i] != ref_out[i])
{
printf("ERROR:%d\n", i);
return -1;
}
}
printf("PASS!\n");
return 0;
}
arm neon汇编实现的性能正好大约是纯C语言实现的16倍。
arm 饱和指令_ARM aarch64汇编学习笔记(九):使用Neon指令(一)相关推荐
- 汇编指令mrs_(转)ARM汇编学习笔记——MRS和MSR指令
MRS,状态寄存器传送至通用寄存器类指令 功能:将状态寄存器的内容传送至通用寄存器. 格式: MRS{}Rd,CPSR}SPSR 其中: Rd 目标寄存器,Rd不允许R15. R=0 将CPSR中 ...
- ARM aarch64汇编学习笔记(一):ARMv8架构
第一期专辑,主要写下自己学习如何在window下使用NDK-BUILD来实现ARM aarch64架构汇编编程. 为何要引入ARMV8: 考虑到ARMV7被市场广泛接受,以及形成的成熟的生态,因此后续 ...
- ARM aarch64汇编学习笔记(二):ARM DS-5模拟器安装和使用
工欲善其事,必先利其器. 使用Qemu 虽然可以进行模拟开发,但在Qemu调试汇编有一些困难. DS-5 (即ARM Development Studio 5) ,是一款针对 ARM 支持的 Linu ...
- 汇编指令msr_(转)ARM汇编学习笔记——MRS和MSR指令
MRS,状态寄存器传送至通用寄存器类指令 功能:将状态寄存器的内容传送至通用寄存器. 格式: MRS{}Rd,CPSR}SPSR 其中: Rd 目标寄存器,Rd不允许R15. R=0 将CPSR中 ...
- 汇编学习笔记——伪指令
目录 伪指令 段定义 结束标记 段关联标记 数据定义 标号 offset指令 seg指令 地址标号 数据标号 代码分段 程序标识 多文件系统 字符输入 重复定义 注释 重复汇编伪指令 伪指令汇总 伪指 ...
- 汇编学习笔记——汇编指令
目录 汇编指令 nop指令 mov.add.sub指令 adc.sbb指令 and.or指令 移位指令 逻辑左/右移指令 循环左/右移指令 算术左/右移指令 带进位循环左/右移指令 inc指令 pus ...
- 汇编学习笔记:对抗反汇编实验2019092801
汇编学习笔记:对抗反汇编实验2019092801 实验描述 实验环境 实验过程 实验结论 实验描述 使用相连的jz和jnz指令跳转到紧接着jnz指令的call指令的第二个字节.call指令实际上无效. ...
- IOS学习笔记(九)之UIAlertView(警告视图)和UIActionSheet(操作表视图)基本概念和使用方法...
IOS学习笔记(九)之UIAlertView(警告视图)和UIActionSheet(操作表视图)基本概念和使用方法 Author:hmjiangqq Email:jiangqqlmj@163.com ...
- python3.4学习笔记(九) Python GUI桌面应用开发工具选择
python3.4学习笔记(九) Python GUI桌面应用开发工具选择 Python GUI开发工具选择 - WEB开发者 http://www.admin10000.com/document/9 ...
最新文章
- 程序员感叹一年只能存下15万太少了……网友:潸然泪下
- 替 ASP.NET 的 Table 控件換裝
- ML之FE:对人类性别相关属性数据集进行数据特征分布可视化分析与挖掘
- SCARA四轴机器人丝杆花键_花键丝杆一体轴型SCARA机器人的制作方法
- 相似图像识别检 —基于图像签名(LSH)
- 工作288:根据时间戳处理接口
- 【原创】Qt自定义窗口部件
- EL表达式,JSP内置对象
- 最短路径之迪杰斯特拉算法
- (转)style,currentStyle,getComputedStyle的区别和用法
- 【网络】解决校园网Wi-Fi登录页无法自动弹出
- 洛谷P3376【模板】网络最大流
- CHM文件制作方法及制作中遇到的坑
- 禁用 Word 2013/2016 信息检索
- 深信服php面经,深信服面经
- 记一次oracle通过dblink连接mysql实施
- C/C++面试/笔试题2022
- xp系统中如何修复浏览器打不开的问题
- Java中的路径:IPath与IFile
- KepOPC全新DA2UA中间件实现OPCDA与UA的转换及互操作
热门文章
- mysql bdb 锁_BDB锁共享区域
- 还在用 Random生成随机数了?试试 ThreadLocalRandom,好用!
- 万万没想到,JVM内存区域的面试题也可以问的这么难?
- TreeSet学习,比较器学习
- dept在Java里面_EmpDeptManager 在JavaEE环境下搭建三大框架体系实现员工的增删改查系统 Develop 261万源代码下载- www.pudn.com...
- 计算机辅助翻译课怎么学的,计算机辅助翻译原理与实践
- 剑指Offer30-包含min函数的栈(单调栈)
- iOS 多页面跳转同一页面时数据处理
- 01、微信公众平台简介及资料文档
- NMEA码详解【转】