neon基础知识

neon介绍

       Neon是适用于ARM Cortex-A系列处理器的一种SIMD(Single Instruction, Multiple Data)扩展结构。NEON有自己的执行管道和寄存器组,neon寄存器组包含32个64位的寄存器16个128位的寄存器,它们分别被标识为(D0-D31),(Q0-Q15)。 实际上D寄存器和Q寄存器是重叠的,如下图所示。NEON 技术本质上是一种并行处理技术,通过并行处理可加速多媒体和信号处理算法(如视频编码/解码、2D/3D 图形等)。通过使用neon可极大的提高软件的性能。

                                                                            


Neon关键概念

1、数据类型

       Neon寄存器可以存放大部分的基本数据类型,如int8、int16等。寄存器可以存放的数据个数跟寄存器大小和数据类型有关。比如64bit的寄存器可以存放8个int8类型数据。而128bit的寄存器则可以存放16个int8类型数据。

2、寄存器---向量(vector)

       在neon中一个寄存器可以看作是一个向量。比如一个64bit的寄存器D0,当这个寄存器存放4个int16类型数据时,可以把它看作是一个向量,它包含了4个类型为int16的元素。
3、管道(lane)---元素

       在上例中,当D0存放4个int16数据时,则此时D0有4个管道,管道0到管道3。管道0位于寄存器的低bit位。这个管道实际就对应了向量的元素概念。

4、Neon的数据装载顺序

       假设一个uint16类型的数组为{0x0201,0x0403,0x0605,0x0807},则它在内存中低地址到高地址存放的顺序为0x01,0x02,0x03````0x08(小端模式)。内存中的数据装入neon寄存器时,是低地址内存数据放入neon寄存器的低地址上,高地址内存数据放入neon寄存器的高地址上。当neon寄存器数据装入内存中时,同样是neon寄存器的低地址数据放入的内存低地址上,neon寄存器的高地址数据放入的内存高地址上。所以内存中的数据经过neon处理后,数据的顺序是不会发生变化的

如何使用Neon

1、intrinsics(内部函数)
       使用intrinsics不如使用汇编优化效率高。但是使用intrinsics较为简单,且容易维护。这些函数在编译的时候会直接转化成Neon的汇编指令。为了支持这些内部函数必须要包含头文件arm_neon.h ,还要通过在编译的时候加入-mfloat-abi=softfp -mfpu=neon,同时需要打开-O2优化选项。使用intrinsics没法控制寄存器分配和内存对齐等。

如:

#include <arm_neon.h>
 uint32x4_t double_elements(uint32x4_t input)
 {
     return(vaddq_u32(input, input));
 }

2、开源库:
       基于neon的开源库如Project Ne10、OpenMAX DL
3、汇编:
       使用neon汇编优化的效果最好但是汇编移植性差,且难度较高。
4、自动向量化(Vectorizing Compilers):
       通过添加一些编译选项来使能向量化编译,让编译器自动生成优化代码,但对于复杂算法就不行了。


Arm-neon网站http://www.arm.com/zh/products/processors/technologies/neon.php


©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页