4000-520-616
欢迎来到免疫在线!(蚂蚁淘生物旗下平台)  请登录 |  免费注册 |  询价篮
主营:原厂直采,平行进口,授权代理(蚂蚁淘为您服务)
咨询热线电话
4000-520-616
当前位置: 首页 > 新闻动态 >
热卖商品
新闻详情
【arm】arm架构64位(AArch64)汇编优化总结 - 灰信网(软件开发博客...
来自 : www.freesion.com/article/16284 发布时间:2021-03-24
1、参考

https://blog.csdn.net/SoaringLee_fighting/article/details/81906495
https://blog.csdn.net/SoaringLee_fighting/article/details/82155608
https://blog.csdn.net/u011514906/article/details/38142177
https://blog.csdn.net/listener51/article/details/82530464

2、前言

     本文是arm架构64位(AArch64执行状态) neon优化的总结文档,主要包括arm架构64位优化的基础知识,特殊用法,打印调试和常用指令使用注意事项以及资料来源等相关知识。前文已有arm架构32位汇编优化总结对arm架构32位neon优化进行了全面总结,并且讲述了arm汇编语法,下面主要以gnu asm汇编语法为例讲述。
下图为arm架构汇编优化总结的思维导图:
\"这里写图片描述\"

3、arm架构64位优化基础知识

  【arm】arm架构64位入门基础:架构分析、寄存器、调用规则、指令集以及参考手册
  该博客已经分析了arm架构64位汇编优化的入门基础知识,主要包括架构分析,寄存器,调用规则,指令集和程序打印调试相关知识,可以作为入门arm64位汇编优化的基础知识。

4、ARMv8/AArch64 neon指令格式

In the AArch64 execution state, the syntax of NEON instruction has changed. It can be described as follows:

 { prefix } op { suffix } Vd. T , Vn. T , Vm. T 

Where:
prefix - prefix, such as using S/U/F/P to represent signed/unsigned/float/bool data type.
op – operation, such as ADD, AND etc.
suffix - suffix
P: “pairwise” operations, such as ADDP,LDP,STP.
V: the new reduction (across-all-lanes) operations, such as ADDV,SMAXV,FMAXV.
2:new widening/narrowing “second part” instructions, such as ADDHN2, SADDL2,SMULL2.
T - data type, 8B/16B/4H/8H/2S/4S/2D. B represents byte (8-bit). H represents half-word (16-bit). S represents word (32-bit). D represents a double-word (64-bit).

For example:UADDLP V0.8H, V0.16BFADD V0.4S, V0.4S, V0.4S

参考自:
https://community.arm.com/android-community/b/android/posts/arm-neon-programming-quick-reference

5、ARM相关编译参数

嵌入式设备(即arm架构的板子)在编译时,最好加上 -fsigned-char 因为嵌入式设备默认类型为unsigned char类型,非char 类型。此外在编译arm汇编优化代码时,编译选项需要加上-c 。-c都表示编译或汇编源文件,但是不进行链接。
ARM相关或者硬件相关编译参数一般以-m开头,常用ARM平台编译选项包括:

-mcpu = cortex-a7
-mabi = atpcs
-march = armv7
-mtune = cortex-a53
-mfpu = neon, neon-vfpv4
-mfloat-api = soft, softfp, hard

更多详细内容可以参考:https://gcc.gnu.org/onlinedocs/gcc-5.2.0/gcc.pdf 3.17.1小节AArch64 option和3.17.4小节 ARM options.

6、查看状态标记位NZCV的方法
mrs x15, nzcvmov w0, w15bl print
7、A64指令集特有的指令及其用法

  1. shl和ushr指令

 shl V . d , V . n , # shift  ushr V . d , V . n , # shift  ushr d2, d2, #8

使用注意事项:这两条指令只能操作64位数据,即只能对D寄存器进行处理。
ushr最多只能进行64位数据的右移,并且右移时会影响V2寄存器的高64位数据(清零),因此高64位数据需要在右移前保存,否则相关数据会被修改。

  2. INS指令
用法与MOV指令基本一样,可以实现neon标量与neon标量之间的传送,以及ARM寄存器与neon标量之间的传送。

INS Vd . Ts [index1], Vn . Ts [index2]INS Vd . Ts [index1], Rn

  3. SUQADD、USQADD指令
既有标量用法,也有矢量用法。

SUQADD V d , V d // signed saturating accumulate of unsigned valueSUQADD Vd . T , Vn . T USQADD V d , V d // unsigned saturating accumulate of signed valueUSQADD Vd . T , Vn . T 

  4. RBIT、REV指令

 RBIT Wd , Wn //reverse bits REV Wd , Wn //reverse bytes

 5. ADDV,SADDLV,SMAXV,SMINV (Vector Reduce(across lanes))

ADDV V d , Vn T // Integer sum element to scalar(vector)SADDLV V d , Vn T // Signed Interger sum elements to long scalar(vector)SMAXV V d , Vn T // Signed Interger maximum elements to scalar(vector)SMINV V d , Vn T // Signed Interger minimum elements to scalar(vector)addv B0, v1.8B // 将v1寄存器中的低64位中8个8位数据相加求和后,赋给v0的最低8位。

更多详细解释可以参考:https://static.docs.arm.com/ddi0487/a/DDI0487A_j_armv8_arm.pdf
\"这里写图片描述\"
 6. sxtw使用注意事项
负数在使用时必须进行符号扩展!
比如:

sxtw x4, w4

  7. w寄存器到v寄存器
直接使用dup指令

dup v0.8B, w2

  8.常用指令对应关系(arm32---- arm64)

 vmovl------ uxtl/sxtl vqmovn----- sqxtn vqmovun----- sqxtun vqrshrun---- sqrshrun vceq------- cmeq vcge------- cmge vadd------ add vsub------ sub vaddl----- saddl,uaddl  vaddw----- saddw,uaddw,sw2addw2,uadd vmull----- smull,smull2,umull,umull2 vmax,vmin----- smax,umax,smin,umin vmlal-------- smlal,smlal2,umlal,umlal2 vrshl-------- urshl,srshl vtrn--------- trn1,trn2 vstm/vstr---- stp/str vld1.32 {d0[]}, [r0], r2----- ld1r {v0.S}[0], [x0], x2 addgt,addle,subgt,suble----- csel,csetm,cset,csinc,csinv

更多可参考:
https://www.element14.com/community/servlet/JiveServlet/previewBody/41836-102-1-229511/ARM.Reference_Manual.pdf

8、资料文档查阅

    在进行arm64位汇编语言编写之前,建议首先阅读学习arm官方英文手册(https://static.docs.arm.com/ddi0487/ca/DDI0487C_a_armv8_arm.pdf) ,重点阅读C7 AArch64 neon指令部分以及C3 ARM指令部分,在了解了基本指令和arm64位汇编格式之后就可以尝试编写了。
    对于已有arm32位代码的情况下,从arm32位代码迁移到arm64时,可以参考(https://www.element14.com/community/servlet/JiveServlet/previewBody/41836-102-1-229511/ARM.Reference_Manual.pdf) 中 5.7.23小节的指令对照表。

    对于代码迁移方法,可以参考我的博客:Some ways of Migrating code from ARM32 to AArch64。

    对于快速查找指令,可以参考指令速查卡:
https://courses.cs.washington.edu/courses/cse469/18wi/Materials/arm64.pdf

9、优化经验总结(满满的干货)关于参数入栈和寄存器入栈
建议将入栈的参数取出之后,再对ARM寄存器或者NEON寄存器进行入栈。尽量去除数据依赖 ,使指令并行
不要将当前指令的目的寄存器作为下一条指令的源寄存器,尤其对于vmul指令,vmla指令。 不要将当前指令的目的寄存器作为下一条指令的源寄存器,尤其对于vmul指令,vmla指令。尽量减少分支跳转
可以采用条件执行指令或逻辑运算指令替代分支跳转,比如addgt,suble,vceq,vcge,vbit,vbsl等。关注指令周期延迟
对于乘法指令,指令周期比较长,尽量不要立即使用指令计算结果,否则会等待耗时。数据运算尽量在neon寄存器中,避免在arm寄存器和neon寄存器之间的运算。尽量减少存取数据的次数。尽量使用不需要保存的寄存器,寄存器出入栈很耗时。对于宽度为4的倍数的情况下,尽量在宽度方向上处理,这样可以提高cache命中率。使用尽量少的指令来编写代码,因为arm指令是精简指令,大部分指令都是单周期指令。如果寄存器够用的话,尽量将一行的数据处理拆成两行或是四行来并行处理;尽量避免大数据之间的运算,可以将大数据的运算拆成小数据的运算。减少循环判断和条件比较
在数据处理过程中,在循环判断或条件判断较多时,可以适当展开分支,可以在一定程度上提升性能。

本文链接: http://archwaystl.immuno-online.com/view-697116.html

发布于 : 2021-03-24 阅读(0)
公司介绍
品牌分类
联络我们
服务热线:4000-520-616
(限工作日9:00-18:00)
QQ :1570468124
手机:18915418616