定义
“ARM Advanced SIMD”,nick-named “NEON”, it provides:
(1)、A set of interesting scalar/vector instructions and registers(the latter are mapped to the same chip area as theFPU ones), comparable to MMX/SSE/3DNow! in the 86 world;
(2)、VFPv3-D32 as a requirement(i.e 32 hardware FPU 64-bit registers,instead of the minimum of 16).
NEON technology as it is used on ARM Cortex-A series processors(比如Cortex-M系列不支持的) that implement the ARMv7-A or ARMv7-R architectures profiles.
The ARMv8 architectural architecture extends the NEON support, and provides backwards compatibility with ARMv7 implementations.
PS:ARM公司将ARM11以后的产品命名为Cortex,并分为A、R和M三个系列。
Cortex系列属于ARMv7架构,是ARM公司最新的指令架构。
由于应用领域的不同,基于v7架构的Cortex处理器系列采用的技术也不相同:基于v7A的Cortex-A系列,基于v7R的Cortex-R系列和基于v7M的Cortex-M系列。
一、ARM Cortex-A系列
该系列面向尖端的基于虚拟内存的操作系统和用户应用,也叫应用程序处理器。
应用包括:智能手机、数字电视、智能本和上网本、家用网关、电子书阅读器等。
二、ARM Cortex-R系列
该系列针对实时系统,面向深层的嵌入式实时应用。
包括:汽车制动系统、动力传动解决方案、大容量存储控制器以及联网和打印。
三、ARM Cortex-M系列
该系类针对微控制器,在该领域中需要进行快速且具有高确定性的中断管理、同时需将门数和可能功耗控制在最低。
包括:微控制器、混合信号设备、智能传感器和汽车电子和气囊。
补充:
ARM7系列——面向普通应用的经典处理器。
ARM9系列——基于ARMv5架构的常用处理器。
ARM11系列——基于ARMv6架构的高性能处理器。
ARM NEON技术可加速多媒体和信号处理算法(如视频编码/解码、2D/3D图形、游戏、音频和语音处理、图像处理技术、电话和声音合成),其性能至少为ARMv5性能的3倍,为ARMv6 SIMD性能的2倍。NEON技术是ARM Cortex-A系列处理器的128位SIMD架构扩展,旨在为消费性多媒体应用程序提供灵活、强大的加速功能。
从ARMv7开始ARM提供高级单指令多数据(SIMD)扩展亦称NEON技术,它是一种由ARM开发的64/128位混合SIMD体系结构,可以提升多媒体和信号处理应用程序的性能。
NEON的寄存器:有16个128位四字寄存器Q0-Q15,32个64位双字寄存器D0-D31,两个寄存器是重叠的,在使用的时候需要特别注意,不小心就会被覆盖掉。
NEON的数据类型:无符号整数、有符号整数、未指定类型的整数、浮点数、{0,1}上的多项式。数据类型针对的是操作数,而不是目标数。NEON中的数据类型说明符由一个指示数据类型的字母构成,该字母通常后跟一个指示宽度的数字。
NEON指令可处理:(1)、由以下内容构成的双字向量:八个8位元素、四个16位元素、两个32位元素、一个64位元素;(2)、由以下内容构成的四字向量:十六个8位元素、八个16位元素、四个32位元素、两个64位元素。
NEON中的正常指令、宽指令、窄指令、饱和指令、长指令:
(1)、正常指令:生成大小相同且类型通常与操作数向量相同的结果向量;
(2)、长指令:对双字向量操作数执行运算,生成四字向量的结果。所生成的元素一般是操作数元素宽度的两倍,并属于同一类型;(注意是和窄指令相反)
(3)、宽指令:一个双字向量操作数和一个四字向量操作数执行运算,生成四字向量结果。所生成的元素和第一个操作数的元素是第二个操作数元素宽度的两倍;
(4)、窄指令:四字向量操作数执行运算,并生成双字向量结果,所生成的元素一般是操作数元素宽度的一半;(和长指令相反)
(5)、饱和指令:当超过数据类型指定的范围则自动限制在该范围内。
NEON标量:有些NEON指令可处理与向量组合使用的标量。NEON标量可以为8位、16位、32位或64位。除乘法指令之外,访问标量的指令也可访问寄存器组中的任何元素。指令语法通过在双字向量中使用索引来引用标量,从而使Dm[x]表示Dm中的第x个元素。乘法指令仅允许使用16位或32位标量,并且只能访问寄存器组中的前32个标量。这在乘法指令中意味着:
(1)、16位标量限定为寄存器D0-D7,其中x位于范围0-3内;
(2)、32位标量限定为寄存器D0-D15,其中x为0或1。
{0,1}上的多项式算法:使用布尔算法规则处理系数0和1:(1)、0+0=1+1=0;(2)、0+1=1+0=1;(3)、0*0=0*1=1*0=0;(4)、1*1=1. 也就是说,将两个{0,1}上的多项式相加与按位异或的运算相同,而将两个{0,1}上的多项式相乘则与整乘的运算相同,但部分积执行的是异或运算,而不是相加运算。
NEON注意事项:
(1)、load数据的时候,第一次load会把数据放在cache里面,只要不超过cache的大小,下一次load同样数据的时候,则会比第一次load要快很多,会直接从cache中load数据;
(2)、在做NEON乘法指令的时候会有大约2个clock的阻塞时间,如果你要立即使用乘法的结果,则就会阻塞在这里。乘法的结果不能立即使用,可以将一些其它的操作插入到乘法后面而不会有时间的消耗;
(3)、使用饱和指令的时候,如乘法饱和的时候,在做乘法后会再去做一次饱和,所用时间要比直接做乘法要慢;
(4)、在对16位数据进行load或者store操作的时候,需要注意的是字节移位。
NEON指令只适用于支持NEON的系统。ARMv7-M不支持NEON。
NEON的指令集只是ARM和THUMB指令集中的子集。NEON的指令都是以V字母开头。使用intrinsics(内联函数)不如使用汇编优化效率高。这些函数在编译的时候会直接转化成NEON的汇编指令。为了支持这些内联函数必须要包含头文件arm_neon.h , 使用NEON技术还要通过在编译的时候加入-mfpu=neon才能起到效果。使用intrinsics没法控制寄存器分配和内存对齐等。
NEON技术只适用于ARM Cortex-A系列处理器。Cortex-A系列处理器:ARMCortex-A系列的CPU处理器内核包括ARMCortex-A5、ARM-A7、ARM Cortex-A8、ARM Cortex-A9 MPCore、ARM Cortex-A9 单核处理器、ARM Cortex-A15 MPCore。ARM Cortex-A系列是一系列用于复杂操作系统和用户应用程序的应用程序处理器。Cortex-A系列处理器支持ARM、Thumb和Thumb-2指令集。
ARM Cortex系列处理器核包括Cortex-A系列(高性能、具备MMU、可以允许如Symbian、Linux、Android、Windows CE等操作系统)、Cortex-R系列(高端嵌入式满足高性能高可靠性的实时需求)、Cortex-M(嵌入式单片机、低功耗、低成本)。
基于ARMv7-A架构的ARM Cortex-A系列处理器(Cortex-A5,Cortex-A7,Cortex-A8,Cortex-A9,Cortex-A15)的基本特性,基本上都可以支持ARM、Thumb-2、Thumb指令集,支持Java加速扩展的Jazelle技术、ThustZone的安全扩展以及针对浮点FPU的VFP硬件扩展和并行多数据的SIMD的NEON多媒体处理器扩展、支持主流的嵌入式OS(Symbian、Linux、Android、WindowsMobile、Windows Phone)、支持分支预测branchprediction.但各处理器在VFP/NEON的类型、半精度浮点(16-bit half precision floating-point)的支持、多核MPcore、流水线pipeline、单MHz处理性能、L1/L2cache控制器、乱序执行、指令dual-issue并发等方面略有不同。
Cortex-A处理器共性:(1)、ARMv7-A体系结构;(2)、对所有操作系统的支持:A、Linux完整分配----Android、Chrome、Ubuntu和Debian;B、Linux第三方----MontaVista、QNX、Wind River;C、Symbian;D、Windows CE;F、需要使用内存管理单元的其它操作系统支持;(3)、指令集支持:ARM、Thumb-2(提供最佳代码密度和性能混用)、Thumb、Jazelle、DSP;(4)、TrusZone安全扩展;(5)、VFP高级单精度和双精度浮点支持;(6)、NEON媒体处理引擎;(7)、支持分支预测branch prediction。
Cortex-A5 ARM核处理器:Cortex-A5处理器支持ARMv7-A架构的特性,包括TrustZone安全扩展NEON多媒体处理引擎,芯片面积和功耗特性很好,但处理性能性对于其他Cortex-A略差,如只相当于Cortex-A8的80%性能,Cortex-A15的一半性能。Cortex-A5可以支持多核。Cortex-A5处理器支持双发dual issue以及分支预测branch prediction。NEON和VFP的硬件可选。Cortex-A5支持ARM和Thumb指令集,并可以包含Jazelle-DBX和Jazelle-RCT的Java加速技术。Cortex-A5 处理器是尺寸最小、功耗最低(可以低至0.08mw~0.12mw/MHz)的 ARM 多核处理器,能够向最广泛的设备提供 Internet 访问:包括超低成本手机、特色手机和智能移动终端以及普遍采用的嵌入式、消费类和工业设备。Cortex-A5 处理器的应用与 Cortex-A8、Cortex-A9 和 Cortex-A15 处理器完全兼容,能够立即访问已得到认可的开发平台和软件体系,包括 Android、Adobe Flash、Java Platform Standard Edition (Java SE)、JavaFX、Linux、Microsoft Windows Embedded、Symbian 和 Ubuntu。Cortex-A5与 Cortex-A8、Cortex-A9 和 Cortex-A15 处理器的完全应用兼容性, 为大量现有 ARM926EJ-S和 ARM1176JZ-S处理器授权使用方提供了高价值的迁移途径。Cortex-A5功耗和面积只有 Cortex-A9 的 1/3,且具有完全的指令集兼容性。特性关键字:VFP, NEON, Jazelle RCT, Thumb/Thumb-2, 1–4 cores,Variable (L1+L2)Cache, MMU+TrustZone。
Cortex-A7 ARM核处理器:Cortex-A7 处理器的功耗和面积与超高效 Cortex-A5 相似,但性能提升 15~20%,Cortex-A7是ARM的大小核设计中的小核部分,并且与高端 Cortex-A15 CPU 体系结构完全兼容。Cortex-A7处理器包括了高性能处理器Cortex-A15的一切特性,包括虚拟化(virtualization)、大容量物理内存地址扩展(Large Physical Address Extensions (LPAE),可以寻址到1TB的存储空间)、NEON、VFP以及AMBA 4 ACE coherency(AMBA4 CacheCoherent Interconnect (CCI))。Cortex-A7支持多核MPCore的设计以及Big+Little的大小核设计。小型高能效的 Cortex-A7 是最新低成本智能手机和平板电脑中独立 CPU 的理想之选,并可在big.LITTLE 处理配置中与 Cortex-A15 结合。特性关键字:VFPv4 FPU, NEON, Thumb-2, JazelleRCT/DBX, out-of-order speculative issue superscalar, Large Physical AddressExtensions(LPAE), Hardware virtualization, 1–4 SMP cores, 32KB/32KB L1, up to4MB L2, MMU+TrustZone。
Cortex-A8 ARM核处理器:Cortex-A8处理器是第一个使用ARMv7-A架构的处理器。很多应用处理器以Cortex-A8为核心,如S5PC100(Samsung),OMAP3530(TI,Texas Instruments),i.MX515(Freescale)。Cortex-A8 处理器是一个双指令执行的有序超标量处理器,针对高度优化的能效实现可提供 2.0 Dhrystone MIPS(每 MHz),这些实现可提供基于传统单核处理器的设备所需的高级别的性能。Cortex-A8在市场中构建了ARMv7体系结构,可用于不同应用,包括智能手机、智能本、便携式媒体播放器以及其他消费类和企业平台。分开的L1指令和数据cache大小可以为16KB或者32KB,指令和数据共享L2 cache,容量可以到1MB。L1和L2 cache的cache数据宽度为128比特,L1cache是虚拟索引,物理上连续,而L2完全使用物理地址。Cortex-A8的L1 cache行宽度为64byte,L2cache在片内集成。另外和Cortex-A9相比,由于Cortex-A8支持的浮点VFP运算非常有限,其VFP的速度非常慢,往往相同的浮点运算,其速度是Cortex-A9的1/10。Cortex-A8能并发某些NEON指令(如NEON的load/store和其他的NEON指令),而Cortex-A9因为NEON位宽限制不能并发。Cortex-A8的NEON和ARM是分开的,即ARM核和NEON核的执行流水线分开,NEON访问ARM寄存器很快,但是ARM端需要NEON寄存器的数据会非常慢。特性关键字:VFP, NEON, Jazelle RCT, Thumb-2, 13-stage superscalarpipeline,Variable(L1+L2)Cache, MMU+TrustZone。使用Cortex-A8的设备:包括Apple的ipad1(apple A4处理器),BeagleBoard (TI OMAP3530 or TI DM 3730)。HTCDesire, SBM7000, Oregon State University OSWALD, Gumstix Overo Earth, Pandora,Apple iPhone 3GS, Apple iPod touch (3rd and 4th Generation), Apple iPad (A4),Apple iPhone 4 (A4), Archos 5, BeagleBoard, Motorola Droid, Motorola Droid X,Motorola Droid 2, Motorola Droid R2D2 Edition, Palm Pre, Samsung Omnia HD,Samsung Wave S8500, Samsung i9000 Galaxy S, Sony Ericsson Satio, Touch Book,Nokia N900, Meizu M9, Google Nexus S, Sharp PC-Z1 "Netwalker。
Cortex-A9 ARM核处理器:Cortex-A9 MPCore或者单核处理器单MHz性能比Cortex-A5 或者Cortex-A8高,支持ARM, Thumb, Thumb-2, TrustZone, JazelleRCT,Jazelle DBX技术。L1的cache控制器提供了硬件的cache一致性维护支持多核的cache一致性。核外的L2 cache控制器(L2C-310, or PL310) 支持最多8MB的cache。Cortex-A9的L1cache行宽度为32byte,L2 cache因为多核的原因在核外集成,即通过SCU来访问多核共享的L2 cache。特性关键字:Application profile, VFPv3 FPU, NEON, Thumb-2, Jazelle RCT/DBX,out-of-order speculative issue superscalar, 1–4 core SMP, 32KB/32KB L1, up to4MB L2, MMU+TrustZone。使用Cortex-A9的设备:包括nVidia's 双核Tegra-2, 以及TI's OMAP4平台,Apple的ipad2(appleA5处理器),LG Optimus 2X(nVidiaTegra-2),Samsung Galaxy S II(Samsung Exynos 4210),Sony NGP PSP2,PandaBoard(TI OMAP4430 or TIOMAP 4460),Motorola Atrix 4G,Motorola DROID BIONIC,Motorola Xoom。
Cortex-A15ARM核处理器:Cortex-A15 MPCore处理器是目前Cortex-A系列中性能最高的处理器,一个突出的特性是其硬件的虚拟化技术(Hardware virtualization)以及大物理内存的扩展(Large Physical Address Extension(LPAE), 能寻址到1TB的内存)。特性关键字:Application profile, VFPv4 FPU,NEON, Thumb-2, Jazelle RCT/DBX, out-of-order speculative issue superscalar, LargePhysical Address Extensions(LPAE), Hardware virtualization, 1–4 SMP cores,32KB/32KB L1, up to 4MB L2, MMU+TrustZone。使用Cortex-A15的设备:目前集成Cortex-A15的处理器量产的只有Samsung的Exynos 5系列处理器,但TI的OMAP5系列处理器也采用Cortex-A15的核。
NEON的流水线在Cortex-A8和Cortex-A9的处理器上不同,NEON的指令一般都是在一个周期内发出,但是执行结果可能若干个周期才能有效,只有简单的如VSUB、VADD和VMOV指令才能在下一个周期可以用。从NEON的寄存器把数据保存到ARM寄存器非常耗时,需要至少20个周期的延时,因而尽量避免这类操作。尽量避免ARM和NEON处理器访问相同的数据区域。
Android NDK NEON
Not all ARMv7-based Android devices will support NEON.
Define LOCAL_ARM_NEON to 'true' in your module definition, and theNDK will build all its source files with NEON support. This can be useful if you want to build a static or shared library that specifically contains NEON code paths.
用 gcc 编译器编译带有neon的文件(ARM NEON Intrinsics),需要添加 -mfloat-abi=softfp -mfpu=neon。
图1 添加 -mfloat-abi=softfp -mfpu=neon
PS: gcc/g++ 编译命令 arm-xilinx-linux-gnueabi-g++ -Wall -O0 -g3 -c -fmessage-length=0 -mfloat-abi=softfp -mfpu=neon -MMD -MP .....................
The NDK supports the compilation of modules or even specific source files with support for NEON. What this means is that a specific compiler flag will be used to enable the use of GCC ARM Neon intrinsics and VFPv3-D32 at the same time.
Neon support only works when targeting the'armeabi-v7a' ABI, otherwise the NDK build scripts will complain and abort. It is important to use checks like the following in your Android.mk:
# define a static library containing ourNEON code
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
include $(CLEAR_VARS)
LOCAL_MODULE := mylib-neon
LOCAL_SRC_FILES := mylib-neon.c
LOCAL_ARM_NEON := true
include $(BUILD_STATIC_LIBRARY)
endif #TARGET_ARCH_ABI == armeabi-v7a
NOT ALL ARMv7-BASED ANDROID DEVICES WILL SUPPORT NEON ! It is thus crucial to perform runtime detection to know if the NEON-capable machine code can be run on the target device.To do that, use the 'cpufeatures' library that comes with this NDK.You should explicitly check that android_getCpuFamily() returns ANDROID_CPU_FAMILY_ARM, and that android_getCpuFeatures() returns a value that has the ANDROID_CPU_ARM_FEATURE_NEON flag set, as in:
#include <cpu-features.h>
...
...
if (android_getCpuFamily() ==ANDROID_CPU_FAMILY_ARM &&
(android_getCpuFeatures() &ANDROID_CPU_ARM_FEATURE_NEON) != 0)
{
// use NEON-optimized routines
...
}
else
{
// use non-NEON fallback routinesinstead
...
}
...
ARM Linux(包括Android) 版本不同,arm_neon.h也略有不同,版本越高,包含的内联函数有可能越多。
Intel Atom processor可以应用到Android,为x86,支持TBB,支持SSE2、SSE3等。
Neon libraries:(1)、projectne10;(2)、OpenMAX;(3)、ffmpeg;(4)、Eigen3;(5)、Pixman;(6)、x264;(7)、Math-neon;(8)、libjpeg-turbo;(9)、Android Skia.
NEON C/C++ intrinsics are available in armcc, GCC/g++,and llvm.
When you compile a file, the compiler must know what processor you want the code to run on.The primary option for doing this is –mcpu=cpu-name,where cpu-name is the name of the processor.If you do not specify the processor to use,GCC will use its built-in default. The default can vary depending on how the compiler was originally built and the generated code might not execute or might execute slowly on the CPU that you have.
There is no support for NEON instructions in architectures before ARMv7.
Load and store addresses must be aligned to cache lines to allow more efficient memory access. This requires at least 16-word alignment on Cortex-A8. If it is not possible to align the start of the input and output arrays, then it is better to process the unaligned elements as single elements. This means some of the elements at the beginning of the array and some of the elements at the end of the array can be processed as single elements.
Neon内联函数包括:加法、乘法、取整、减法、比较、绝对差、最大、最小、逻辑运算、获取lane值、设置lane值、合并、分离、类型转换、查表、Load、Store等运算,总共近1900条指令。