前言

在上一篇中我们讲了SIMD技术的基础和前世今生,可以结合上一篇文章一起看大前端CPU优化技术--SIMD技术。今天我们全局性地讲解下NEON技术​。

目前主流的移动设备以ARM v7和v8版本架构占据了绝大多数的江山,随着近几年64位手机的普及和各大应用市场的强推下,64位的v8呈崛起之势。

ARM在ARMv5 架构开始引入 VFP(vector-floating-point) 指令扩展,可以通过使用短向量指令来加速浮点计算。

armv6架构中已经提出了一些simd的指令,可将多个16bit,8bit的数据加载到32bit寄存器中,但是并没有单独的执行单元也没有单独的流水线。指令名字就是在之后加16或8的后缀。

armv7开始引入了advanced SIMD,定义了自己的向量寄存器,32*64bit register file,自己的流水线执行单元。这些SIMD的扩展被称为NEON。

NEON

在32-bit内核的处理器上,如Cortex-A系列,如果不采用SIMD则会将大量时间花费在处理8-bit或16-bit的数据上,但是处理器本身的ALU、寄存器、数据深度又是主要为了32-bit的运算而设计的。因此NEON应运而生。

NEON就是一种基于SIMD思想的ARM技术,相比于ARMv6或之前的架构,NEON结合了64-bit和128-bit的SIMD指令集,提供128-bit宽的向量运算(vector operations)。

ARM NEON 技术本质上是一种高级的单指令多数据(SIMD)架构扩展,这种扩展仅在ARM Cortex-A 和 Cortex-R 系列处理器中使用。ARM NEON 单元默认包含在 Cortex-A7 和 Cortex-A15 处理器中,但在其他 ARMv7 Cortex-A 系列处理器中是可选的,某些实现 ARMv7–A 或 ARMv7–R 架构配置文件的Cortex-A 系列处理器可能不包含NEON单元。

NEON演进史


NEON 技术是依靠向量指令来加速计算,而鉴于 NEON 技术比VFP(vector-floating-point)提供的向量技术加速效果体验更优秀,从 ARMv7 架构开始使用 VFP 向量指令加速的模式被弃用。

在ARMv7中,NEON 与 VFP 指令集具有以下关系:

  • 具有 NEON 单元但没有VFP单元的处理器无法在硬件中执行浮点运算。
  • 由于 NEON SIMD 操作更有效地执行向量计算,因此从 ARMv7 的引入开始,VFP 单元中的向量模式操作已被弃用。因此,VFP 单元有时也称为浮点单元(FPU)。
  • VFP 可以提供完全兼容 IEEE-754 的浮点运算,ARMv7 NEON 单元中的单精度运算不完全符合 IEEE-754
  • NEON不能取代 VFP。VFP 提供了一些在 NEON 指令集中没有等效实现的专用指令。
  • 半精度指令仅适用于包含半精度扩展的 NEON 和 VFP 系统。
  • 在ARMv8中,VFP已被NEON取代,以上问题如 NEON 并不完全符合 IEEE 754 标准,并且有一些指令 VFP 支持而 NEON 不支持的问题已在 ARMv8 中得到解决。

再加上NEON本身也仅在部分处理器上才支持,所以必须首先确认处理器是否支持 NEON 和 VFP。可以在编译和运行的时候进行检查。需要注意的是neon可以和vfp同时使用,但由于寄存器是公用的。ARMv7 有 32 个 NEON D 寄存器,如下图所示

编译/运行时检查

编译期可在 ARM 编译器工具链(armcc)v4.0 及更高版本或 GCC 中,检查预定义宏 __ARM_NEON__ 或者 __arm_neon 是否开启。

运行时检测 NEON 单元需要依赖操作系统的能力,由于 /proc/cpuinfo 输出是基于文本的,因此通常首选查看辅助向量 /proc/self/auxv,其包含二进制格式的内核 hwcap,可以轻松地在 /proc/self/auxv 文件中搜索 AT_HWCAP 记录,以检查 HWCAP_NEON 位(4096)。

NEON架构

熟悉 ARMv7-A 架构的应该知道 ARMv7 架构的内核是一个32位的系统,使用32位的寄存器。但是 NEON 单元使用的是64位或者128位的寄存器。这里的原因就是 NEON 单元使用独立的寄存器文件。不过,NEON 单元还是完全集成到处理器中的,可以和处理器共享整型操作单元、循环控制和缓存资源,相比于使用硬件加速器,大大降低了面积和功耗成本。而且由于 NEON 单元和应用程序使用相同的地址空间,可以使用更简单的编程模型。

ARM NEON 技术的核心是 NEON 单元,主要由四个模块组成,分别是 NEON 寄存器文件、整型执行流水线、单精度浮点执行流水线和数据加载和重排流水线。

The components of the unit are:

  • Neon register file
  • Neon integer execute pipeline
  • Neon single-precision floating-point execute pipeline
  • Neon load/store and permute pipeline

NEON 寄存器

NEON 寄存器主要是用来存放包含相同数据类型元素的向量。在 ARMv7 架构中, 一共有16个128位寄存器,这个128位寄存器也称之为 Q 寄存器,一个128位寄存器又可以分为两个64位寄存器,即一共有32个64位寄存器,64位寄存器又称之为 D 寄存器。在ARMv8 架构中寄存器的数量相比 ARMv7 架构数量翻倍。Q 寄存器和 D 寄存器对应表如下所示:

注:每一个Q0-Q15寄存器映射到一对D寄存器。

寄存器之间的映射关系:

  • D<2n> 映射到 Q 的最低有效半部;
  • D<2n+1> 映射到 Q 的最高有效半部;

结合NEON支持的数据类型,NEON寄存器有如下图的几种形态:

NEON指令执行

上图为 NEON 单元完成加速计算的流程图。其中向量寄存器中的每个元素同步执行计算,以此来加速计算过程。

NEON指令类型

NEON指令按照操作数类型可以分为正常指令、宽指令、窄指令、饱和指令、长指令。

  • 正常指令:生成大小相同且类型通常与操作数向量相同到结果向量。
  • 长指令:对双字向量操作数执行运算,生成四字向量结果。所生成的元素一般是操作数元素宽度到两倍,并属于同一类型。用L标记,如VMOVL。
  • 宽指令:一个双字向量操作数和一个四字向量操作数执行运算,生成四字向量结果。用W标记,如VADDW。
  • 窄指令:四字向量操作数执行运算,并生成双字向量结果,所生成的元素一般是操作数元素宽度的一半。用N标记,如VMOVN。
  • 饱和指令:当超过数据类型指定的范围则自动限制在该范围内。用Q标记,如VQSHRUN

NEON指令调用

ARM 平台提供了四种使用 NEON 技术的方式,分别为 NEON 内嵌函数、NEON 开源库、编译器自动向量化和 NEON 汇编。

NEON内嵌函数

NEON 内嵌 函数提供了一种编写 NEON 代码的方法,该方法比汇编代码更易于维护,同时仍然可以控制生成的 NEON 指令。

内部函数使用与 D 和 Q NEON 寄存器对应的新数据类型。数据类型支持创建直接映射到NEON 寄存器的 C 变量。

NEON 内嵌函数调用类似于普通函数调用,通过调用函数接口告知编译器需要优化的代码,编译器在编译阶段直接使用 NEON指令替换这些内嵌函数而不是执行类似子函数调用的操作。NEON 内嵌函数提供了一种低级的 NEON 指令访问方式,编译器做了一些通常与编写汇编语言相关的繁重工作来达到获取最高性能的目标,例如:

  • 寄存器分配
  • 代码调度或重新排序指令

NEON 内嵌函数的缺点在于无法让编译器准确输出想要的代码,因此在转向NEON汇编代码时仍有一些改进的可能性。

自动矢量化

向量化编译器可以将C或C++源代码进行矢量化,以实现对NEON硬件的有效使用。这意味着尽管开发者开发可移植的C或C++源码,也可能通过矢量编译器的自动向量化功能享受到NEON指令带来的性能提升。GCC和ARM编译器均能通过配置编译选项开启自动向量化,从而使用NEON技术优化代码。如果编译器能够确定开发者的意图,矢量化编译器可以以最优的方式优化代码。相较于针对某一特定处理器高度调整的代码,易于人们理解的简单代码更容易向量化。

NEON开源库

鉴于 NEON 指令的强大优化效果,市场上出现了很多支持 NEON 优化的开源库,比如 Ne10、OpenMAX、ffmpeg、Eigen3和Math-neon等

NEON汇编

对于性能要求特别高的程序,手工编写汇编代码是更适合的方式。

GNU 汇编器(gas) 和 ARM Compile r工具链汇编器(armasm)都支持 NEON 指令的汇编。

 其他平台上的 SIMD 技术

SIMD 处理不是 ARM 独有的,下图将其与 x86 和 Altivec 进行了比较。

专用 DSP 对比

许多基于 ARM 的 SOC 中还包含 DSP 等协处理硬件,因此可以同时包含 NEON 单元和DSP。相对于 DSP,NEON 的特点有:

  • 扩展了ARM 处理器流水线
  • 使用 ARM 内核寄存器进行内存寻址- 简易的开发和调试
  • SMP 能力。MPCore 处理器中的每个 ARM 内核都有一个 NEON 单元。
  • 开源社区和ARM生态系统都提供了广泛的 NEON 工具支持

DSP特点:

  • 与 ARM 处理器并行运行
  • 与 ARM 处理器集成度较低。在 DSP 和 ARM 处理器之间传输数据可能会有一些缓存清理或刷新开销。

总结

本文主要介绍了NEON的基本原理、寄存器、指令调用等基础知识,但NEON 技术所能探讨的内容远不止于此,后续也将会更深入的研究。

大前端CPU优化技术--NEON技术相关推荐

  1. 大前端CPU优化技术--NEON指令介绍

    前言 ARM NEON 可以提升音视频,图像,计算机视觉等计算密集型程序的性能,在上一篇大前端CPU优化技术--NEON技术的介绍中,我们知道一些编译器可以将 C/C++ 代码自动转换为 NEON 指 ...

  2. 大前端CPU优化技术--NEON intrinsics进阶

    前言 今天我们继续介绍NEON intrinsics的指令知识,上篇大前端CPU优化技术--NEON intrinsics开篇中已经介绍了部分指令的作用.本篇文章除了介绍指令还会附上场景示例,方便大家 ...

  3. 大前端CPU优化技术--NEON自动向量化

    前言 ARM NEON技术是一种高级的单指令多数据的架构扩展的实现.它是一种64位和128位混合的SIMD技术,主要应用场景是音视频处理,图像视觉计算,信号处理应用等需要密集计算的场景. NEON技术 ...

  4. 大前端CPU优化技术--NEON编程优化技巧

    前言 在前面的文章中我们介绍了NEON的基础,NEON技术的全景,指令及NEON intrinsic指令,相信大家能通过前面的学习写一些简单的NEON程序.但要想写好一个性能高的NEON程序,远不止你 ...

  5. 林云会研究院参加“创新大前端 研发新思路”线下技术沙龙活动

    2022年9月25日,由凡泰极客主办.优姆领克协办的"创新大前端.研发新思路"线下技术沙龙活动在南山科技园桑达科技大厦蓝马咖啡成功举办,林云会数字经济研究院应邀出席活动,与业内资深 ...

  6. 前端性能优化之缓存技术

    缓存一直以来都是用来提高性能的一项必不可少的技术 , 利用这项技术可以很好地提高web的性能. 缓存可以很有效地降低网络的时延,同时也会减少大量请求对于服务器的压力. 接下来这篇文章将会详细地介绍在w ...

  7. 前端18个月难度翻番?来这里把握大前端技术本质进展丨稀土开发者大会

    图片来源:pexels.com "别更新了,学不动了"向来是前端开发群体的切肤之痛: React 还没学明白,Vue 就出来了: Vue 2.0 还没上手,3.0 就发布了: No ...

  8. 2021大前端技术储备

    GMTC GMTC全球大前端技术大会是由极客邦科技旗下InfoQ中国主办的技术盛会,关注前端.移动.AI应用等多个技术领域,促进全球技术交流,推动国内技术升级.GMTC为期4天,包括两天的会议和两天的 ...

  9. 2019年一半已过,这些大前端技术你都GET了吗?- 下篇

    在上一篇文章中已经介绍了大前端关于状态管理.UI组件.小程序.跨平台和框架层的内容.在本文中,我会继续介绍编程语言.工程化.监控.测试和服务端,同时也会对下半年大前端可以关注的部分进行展望. 结合个人 ...

最新文章

  1. ie9下console不兼容的问题
  2. 计算机二级怎么更改报名密码忘记了怎么办,中考报名系统密码忘了怎么办
  3. GE前董事长伊梅尔特谈数字化转型:制造企业这件事做不好,一定没出路
  4. 实现runable接口创建线程
  5. JS写纸牌发牌和动画(详细解剖)
  6. oracle 解死锁权限,讲解Oracle数据库中结束死锁进程的一般方法
  7. Eclipse取消Process Validating
  8. android 原型模式,原型模式-下拉刷新的全局设置
  9. QT高级编程技巧(二)-- 编写多线程和并发应用
  10. win10商店下载位置_手把手教您win10应用商店安装目录在哪的详尽处理门径
  11. 要实现动态加载JS脚本有4种方法:
  12. unity3d模型制作规范
  13. 【OpenCV学习】cvtColor
  14. 1.13 08特殊日历计算
  15. 微信小程序如何实现点击链接跳转到手机自带浏览器
  16. 小程序源码:喝酒娱乐小游戏助力神器-多玩法安装简单
  17. 小白如何入门单片机?几个建议助你提高学习效率,把握学习方向
  18. 解决vue的跨域问题
  19. 【_ 記 】SpringBoot注解 (最新最全最详细)
  20. Python_Task06:函数与Lambda表达式

热门文章

  1. 关于杂项(bugku平台)(持续更新)
  2. RMAN备份归档日志时的not backed up与catalog数据库结合时的问题
  3. 深度linux打不开了,深度社区严重打不开
  4. 粗略的了解Javascript
  5. 你的善良必须有点锋芒
  6. 《沙丘》全球票房突破3.5亿美元,这部科幻巨制到底有多厉害?
  7. tushare实盘交易接口
  8. CKPlayer视频地址加密方法
  9. 【小程序开发之微信登录】
  10. 在电脑中怎样画思维导图