DSP

ARM Neon基础知识(二)

2019-07-13 16:48发布

1. 下面介绍了微处理器指令处理数据的常用方法:         A. 单指令单数据SISD(Single Instruction Single Data)         B.  单指令多数据SIMD(Single Instruction Multiple Data)向量模式         C.  单指令多数据SIMD(Single Instruction Multiple Data)压缩数据模式
A. 单指令单数据SISD        每个指令指定单个数据源进行处理,处理多个数据项需要多个指令。这种处理方式比较慢,而且数据项分布在不同的寄存器中,很难看出数据项的相关性。为了改善性能和效率,媒体处理经常被加载到诸如GPU(Graphics Processing Unit)或者多媒体处理单元(Media Processing Unit)这样的专用处理器中,他们可以用单指令处理多数据。在ARM 32位处理器上,处理大量8-bit或16-bit数据并没有有效利用处理器资源,因为处理器,寄存器、数据总线这些都是32位的。如下面所示的加法操作,每一操作元都是单个数据:                               add r0, r5
                              add r1, r6
                              add r2, r7
                              add r3, r8
B. 单指令多数据SIMD(向量模式)        操作可以指定对多个数据源进行相同的处理。若控制寄存器中LEN长度为4,则单个向量加法指令在4个地址上执行。在ARM术语中,这被称为向量浮点运算。在ARMv5架构中引入了向量浮点(VFP)扩展执行短向量指令以加速浮点运算。源和目标寄存器可以是标量操作的单个寄存器,也可以是两个序列(8个寄存器)的矢量操作。因为SIMD操作比VFP操作更有效地执行向量计算,矢量模式操作在ARMv7上被弃用,取而代之的是NEON技术在宽寄存器上执行多种操作。浮点和NEON的操作使用共通的通用寄存器。
                              VADD.F32 S24, S8, S16
                              // four operations occur
                              // S24 = S8 +S16
                              // S25 = S9 +S17
                              // S26 = S10 +S18
                              // S27 = S11 +S20

C. 单指令多数据SIMD(打包数据模式)         操作可以指定对存储在一个大的寄存器中的多个数据字段进行相同的处理。这样的操作在ARM术语中叫做Advanced SIMD technology or NEON technology.
        图中所示的加法操作是真正独立的,数据的溢出或移位不会对前面数据的末位产生影响,数据之间是独立计算的。                               VADD.I16 Q10, Q8, Q9
                              // One operation adds two 64-bit registers,                               // but each of the four 16-bit lanes in the register is added separately.                               // There are no carries between the lanes                                                                                        64-bit寄存器的数据可以分为:两个32位,四个16位,或八个8位整数数据元素可以同时在一个64位寄存器中进行操作;         128-bit寄存器的数据可以分为:四个32位,八个16位,或16个8位整数数据元素可以同时在一个128位寄存器中进行操作;
 
        媒体处理器,如在移动设备中,通常将每个完整的数据寄存器分割成多个子寄存器并在子寄存器上并行的执行计算。如果处理数据集简单且重复多次,SIMD可以提供相当大的性能改进。它特别有利于数字信号处理或多媒体算法,如:         a. 音频、视频和图像处理编解码器;         b. 基于矩形块的二维图形;         c. 三维图形;         d. 颜 {MOD}空间转换
2.  ARM NEON和其他技术的比较         A.  NEON技术和ARMv6 SIMD.         B.  NEON技术和其他SIMD技术         C.  NEON技术和数字信号处理器
A.   NEON技术和ARMv6 SIMD.         ARMv6体系结构引入了一组SIMD指令,这些指令用于在标准32位ARM通用寄存器上操作多个数据(16位或8位),这些指令允许某些操作在不任何附加计算单元的情况下执行两到四次额外的计算单位, 下图展示了4个8-bit整型数在32-bit通用寄存器上的加法运算,UADD8 R0, R1, R2 :                                                             
         ARM NEON技术基于SIMD的概念,支持128位的矢量运算而不是ARMv6架构中的32位向量操作,下表列举了ARMv6 SIMD和ARMv7 NEON技术的特点:                       B.   NEON技术和其他SIMD技术         SIMD处理技术不是ARM架构所独有的,其他平台上也支持SIMD技术,可以将他们与ARM NEON技术作对比, 下面图示对比了ARM NEON和X86 MMX/SSE技术特点:                          C.  NEON技术和数字信号处理器         许多ARM处理器也包含数字信号处理器(DSP)或自定义信号处理硬件,所以ARM微处理器可以包括一个NEON单元和一个DSP。使用NEON和DSP还是有很大区别:         NEON技术特点:             a. 扩展了ARM处理器的pipeline.             b. 使用ARM核心寄存器作为内存地址.             c. 单线程控制提供了更容易的开发和调试.             d. 操作系统支持多任务.             e. 对称多处理器支持, 每一个ARM核都附有一个NEON单元,支持多线程处理.             f. 作为ARM架构的一部分,将来更多的ARM处理器将支持NEON特性.
            g. 开源社区更多地工具集以及ARM生态系统.         DSP特点
            a. 与ARM处理器并行.             b. 匮乏的OS及任务切换带来的性能问题。             c. 与开发大多数应用不同,不同的工具集,不同的调试,潜在的同步问题等。             d. 与ARM处理器集成度低,指令cache和数据cache的刷新将导致DSP和ARM之间传输效率低下。
3.  对NEON技术的架构支持         在ARMv7-A和ARMv7-R上已经支持NEON技术,ARMv8架构架构扩展了NEON支持,并提供了向后兼容ARMv7实现;不能担保当前使用的平台上支持NEON或者VFP技术;若处理器支持NEON但不支持VFP技术,则不能在硬件上进行浮点运算,  因为NEON SIMD执行向量运算比较高效,且VFP的向量操作模式在ARMv7上被取消。
          指令周期: 指令周期没有做限定,因为有些时候指令和数据并不一定都在Cache中。
        仅支持VFP的系统: 有些指令在NEON和VFP上是共用的,这些指令叫做共享指令;VFP和NEON单元都使用CP10和CP11的协处理器指令空间和共享相同的寄存器,这两种情况下会导致某些冲突:         a.  VFP可以提供完全IEEE-754兼容的浮点运算, 这完全依赖于实现,可操作单精度和双精度浮点数据。         b.  NEON单元支持整数和单精度浮点数的并行数据处理,但单精度并不完全兼容IEEE-754;         c.  NEON不能替代VFP,VFP有一些专门的指令,在NEON指令集中没有等效的实现;

4.  NEON基础知识         如果你对ARMv7-A架构比较熟悉,那么你应该知道ARMv7是32bit架构,寄存器也是32-bit,但NEON单元的SIMD处理使用64-bit或128-bit寄存器。这种情况是可能的,因为NEON单元和VFP是ARMv7指令集的扩展,它在一个独立单元中访问64位寄存器,NEON和VFP单元是完全的集成到处理器,并共享处理器资源进行整数操作,循环控制和缓存。与硬件加速器相比,这大大减少了布局和能耗成本。它还使用了一种更简单的编程模型,因为NEON单元和应用程序使用相同的地址空间。         NEON的组成部分包括:             a.  NEON寄存器             b.  NEON整型数据计算过程             c.  NEON单精度浮点计算过程             d.  NEON加载/存储和交换过程
 A.  寄存器,向量,轨道和元素         NEON指令和浮点指令使用相同的寄存器,统称为:NEON and floating-point register.这与ARM核心寄存器不同, 可以按32-bit,64-bit或者128-bit来访问寄存器,到底是使用那种类型的寄存器完全取决于指令集。NEON寄存器和ARM通用寄存器数据交换,ARM通用寄存器和内存地址数据交换。NEON寄存器中的数据被看作同一数据类型的向量元,一个向量被分成轨道和轨道内包含的数据元。通常情况下,每一个NEON指令都会产生n个并行的操作,其中n是输入向量被分成的轨道数,每个操作都在其轨道内进行,不能垮轨道进行数据的操作。         数据元顺序         数据元的存取遵循小端字节序,如图所示,数据低位存储在寄存器低地址段。                                                          图中列举了8个16-bit整型数据元的加法操作(VADD.I16 Q0, Q1, Q2):                                                                                 寄存器复用
        图中展示了NEON寄存器和浮点寄存器的复用方式         NEON寄存器展示:             16个128-bit Q寄存器:Q0~Q15;             32个64-bit D寄存器: D0~D31(在VFPv3-D16版本中,也可作为16个64-bit的D寄存器);
                                                                     所有这些寄存器在任何时候都可以访问。 软件不需要显式切换, 因为使用的指令决定了寄存器的类型。        下图展示了S、D、Q寄存器的对应(以Q0为例):
       NEON可以将Q0最为128-bit寄存器访问,也可以将128-bit寄存器Q0分为两个64-bit的寄存器D0和D1访问;
       NEON不能访问Q0中32-bit的S寄存器,若VPF支持,则它可以访问将Q0分为四个32-bit寄存器S0、S1、S2、S3访问;                                                         标量数据         标量是指单个值,而不是包含多个值的向量。有些NEON指令使用标量操作数,NEON寄存器内的标量由索引访问到向量的值。下面的图示展示了标量怎样被赋给向量数据元(VMOV.8 D0[3], R3)。                                                           NEON标量可以是8-bit,16-bit,32-bit,64-bit值,除乘法指令以外,其他的标量访问指令可以访问任意寄存器数据元。         乘法指令只允许访问16-bit和32-bit标量,而且只能访问寄存器的前32个标量数据元。                 16-bit标量被限制在D0[x]---D7[x],x范围为0到3;                 32-bit标量被限制在D0[x]---D15[x], x范围为0到1;
B.  NEON数据类型指定         尽管ARM架构没有要求一个处理器必须实现VFP和NEON基础,但在通常的编程过程中支持VFP的代码几乎不需要修改可以支持NEON技术。但是在有些Cortex-A系列处理器上NEON技术是可选项,不能保证基于NEON的代码可以在所有的处理器上很好的运行。         若要编写基于VFP或NEON技术的代码,在编译的时候应该判定目标平台是否支持。在VFP和NEON的指令中已经包含了要操作的数据类型和数据宽度,他们与指令助记符以点号(.)分开,如:VMLAL.S8。 下表列出了NEON指令的数据类型:                                                                     C.  VFP下NEON和浮点寄存器的视图         ARMv7A和ARMv7R架构实现了可选的VFP变体如下表所示: