历史上的今天
返回首页

历史上的今天

今天是:2025年02月07日(星期五)

正在发生

2020年02月07日 | arm架构64位(AArch64)汇编优化总结

2020-02-07 来源:eefocus

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:


{}{}  Vd., Vn., Vm.  

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.16B

FADD 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, nzcv

mov  w0,  w15

bl print


7、A64指令集特有的指令及其用法

1. shl和ushr指令

shl  ., ., #

ushr  ., ., #

ushr  d2, d2,  #8

使用注意事项:这两条指令只能操作64位数据,即只能对D寄存器进行处理。

ushr最多只能进行64位数据的右移,并且右移时会影响V2寄存器的高64位数据(清零),因此高64位数据需要在右移前保存,否则相关数据会被修改。


2. INS指令

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


INS   .[index1], .[index2]

INS   .[index1], Rn


3. SUQADD、USQADD指令

既有标量用法,也有矢量用法。


SUQADD ,      // signed saturating accumulate of unsigned value

SUQADD ., .

USQADD ,     // unsigned saturating accumulate of signed value

USQADD ., .


4.RBIT、REV指令


 RBIT , //reverse bits

 REV ,   //reverse bytes

5.

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

ADDV ,     // Integer sum element to scalar(vector)

SADDLV ,   // Signed Interger sum elements to long scalar(vector)

SMAXV ,    // Signed Interger maximum elements to scalar(vector)

SMINV ,    // Signed Interger minimum elements to scalar(vector)


eg.:

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指令是精简指令,大部分指令都是单周期指令。

如果寄存器够用的话,尽量将一行的数据处理拆成两行或是四行来并行处理;尽量避免大数据之间的运算,可以将大数据的运算拆成小数据的运算。


减少循环判断和条件比较

在数据处理过程中,在循环判断或条件判断较多时,可以适当展开分支,可以在一定程度上提升性能。


THE END!


推荐阅读

史海拾趣

驰兴电感(Coilank)公司的发展小趣事

驰兴电感始终坚持“品质第一”的原则,对产品的每一个细节都进行严格把控。公司引进了先进的生产设备和检测仪器,确保产品从原材料到成品的每一个环节都符合高标准的质量要求。这种对品质的执着追求,使得驰兴电感的产品在市场上赢得了良好的口碑,树立了高品质的品牌形象。

光磊(GL)公司的发展小趣事

随着电子行业的快速发展,驰兴电感紧跟市场趋势,不断拓展产品应用领域。除了传统的消费电子和通讯领域外,驰兴电感还成功将产品应用于汽车电子、网络通讯、智能家居等新兴领域。这些领域的拓展不仅为公司带来了更广阔的市场空间,也进一步提升了驰兴电感在电子行业中的地位。

台湾稳态公司的发展小趣事

随着企业规模的扩大和影响力的提升,台湾稳态公司开始积极承担社会责任,推动可持续发展。公司注重环保和节能技术的应用,致力于生产环保型电子产品,减少生产过程中的能源消耗和环境污染。同时,稳态公司还积极参与社会公益事业,为社会的发展贡献自己的力量。

这些故事虽然基于假设,但反映了电子行业企业普遍面临的挑战和机遇,以及台湾企业在该行业中的发展特点。如需了解台湾稳态公司的真实发展故事,建议查阅相关新闻报道或访问公司官方网站。

Changzhou Galaxy Century Microelectronics Co.,Ltd公司的发展小趣事

银河微电自成立之初,便专注于半导体分立器件的研发与生产。面对国内外市场的激烈竞争,公司坚持自主创新,不断投入研发力量,终于在某关键技术上取得了重大突破。这一技术突破不仅提高了产品的性能,还降低了生产成本,使得银河微电的产品在市场上更具竞争力。凭借这一技术优势,银河微电逐渐在行业中树立起了自己的地位。

CWIND公司的发展小趣事

随着全球对环保和可持续发展的重视程度不断提高,CWIND公司积极响应这一趋势,将绿色环保理念融入到产品研发和生产过程中。公司投入大量资金和资源,研发出了一系列符合环保标准的电子产品,并优化了生产工艺,减少了废弃物和污染物的排放。这一举措不仅提升了CWIND的品牌形象,还为公司赢得了更多的市场份额。

Holy Stone公司的发展小趣事

Holy Stone企业股份有限公司创立于1981年,总部位于台北市。创立之初,公司凭借创办人深厚的电子技术背景,迅速在电子元件市场站稳脚跟。起初,Holy Stone主要作为专业的电子零件代理商,为客户提供专业的技术服务与解决方案。这一阶段,公司通过扎实的专业技术基础和敏锐的市场洞察力,逐步建立起稳定的客户基础,为后续的发展奠定了坚实的基础。

问答坊 | AI 解惑

有没有纯数字的精确测量信号时间间隔的方法?

十个ns左右的误差范围啊,疯了都,目前我想到两个方法,一个是精确扩展计数时间,一个是多测几次,牺牲测量速度,不好弄…

查看全部问答>

HI-TECH C V9.70 和谐文件

HI-TECH C Compiler for PIC10-12-16 MCUs V9.70 已经测试过,破解成功! 1,先安装HI-TECH C Compiler for PIC10-12-16 MCUs V9.70  安装路径为默认路径 \"C 盘下\" 激活PICC 45天试用版! 2,破解,先写入注册文件,运行破解文件, ...…

查看全部问答>

DDRAW程序问题,在全屏方式下,用创建程序的方式打开一个程序后,程序的界面显示不出来,LCD上显示的还是DDRAW的画面

请问如何解决这个问题 // // Copyright (c) Microsoft Corporation.  All rights reserved. // // // Use of this source code is subject to the terms of the Microsoft end-user // license agreement (EULA) under which you l ...…

查看全部问答>

求助 :最近学习uc/os-ii 用的任哲写的《嵌入式实时操作系统uc/os-ii原理及应用》编译无法通过

最近学习uc/os-ii  用的任哲写的《嵌入式实时操作系统uc/os-ii原理及应用》,把他书中的源码在网上找到了。书中是用的BORLAND C++ 3.1编译的,我用borland c v3.1 dos 界面下直接建立工程文件编译,可是搞了很久编译都无法通过,而且试了 ...…

查看全部问答>

wince usb 驱动问题

我在看wince5.0 usb从驱动源代码具体位置是:/%wince500boot%/public/common/oak/usbfn 这个文件下有3个文件夹: 1.CLASS文件: RNDIS,SERIAL, STORAGE三个文件夹 2.CONTROLLER文件: MDD,NET2280 3.UFNCLIENLIB文件 请问这三个文件都有什 ...…

查看全部问答>

求助 AT89S51与C8051F单片机有什么区别啊?(急)

   各位前辈,我是一名学生菜鸟,要用单片机做采集器,遇到了这么一个问题,AT89S51与C8051F单片机有什么区别,请各位帮忙解决,谢谢!…

查看全部问答>

有木有CH4浓度传感器啊,急求资料,帮忙呀

最还好有单片机程序代码,电路图等等,越全越好.谢谢啊 …

查看全部问答>

4-20ma转换成0-5V

各位高手,本人摸电只是懂点基本的.想请教大家个问题.传感器输出的4-20ma如何转换成0-5V.我以前一直就是用250欧电阻将4-20ma转换成1-5V,再进行A/D转换,感觉这样处理没有0-5V方便.比如4-20ma表示0-50度的温度,0V的时候就表示温度是0度,5V的时候就表示 ...…

查看全部问答>

MSP430 LaunchPad学习笔记之uart

一、摘要本应用报告介绍了如何使用Timer_A实现UART功能。该包括例子是专门为MSP430x11x家庭,但他们能适应任何MSP430家族成员纳入Timer_A。使用硬件UART的功能在Timer_A功能和软件。执行是半双工的,事件驱动,它支持的8N1波特率协议从1200到115200 ...…

查看全部问答>

求一个G2452 SPI模式传输的例程

如题,望大家帮忙,谢谢!!…

查看全部问答>