简介
NEON是作为一种附加的加载/存储架构设计的,它为C/C++等语言提供了良好的向量化编译器支持。这使得并行性水平很高。你可以为需要极高性能的应用手动编写NEON指令。它包括低成本的数据大小提升和降级。它还包括结构加载,能够访问在内存中交错的多个数据流。
NEON指令可以作为常规ARM代码的一部分编写。这使得NEON编程比使用外部硬件加速器更简单、更有效。有NEON指令可用于读写外部内存,将数据在NEON寄存器和其他ARM寄存器之间移动,以及执行SIMD操作。
所有编译的代码和子程序将符合EABI,它指定了哪些寄存器可以被破坏,哪些寄存器必须被保留。
向量化编译器可以获取你的C或C++源代码,并以一种方式向量化它,以实现NEON硬件的有效使用。这意味着你可以编写可移植的C代码,同时仍然获得NEON指令所提供的高性能水平。
为了协助向量化,使循环迭代次数成为向量长度的倍数。GCC和ARM编译器工具链都有选项可以启用NEON技术的自动向量化,但由于C和C++标准不包括并发性方面,你可能需要向编译器提供额外的信息以获得全部好处。所需的源代码修改是标准语言规范的一部分,因此它们不会影响不同平台和架构之间的代码可移植性。
当编译器能够确定程序员的意图时,向量化编译器的效果最好。对于人类来说容易理解的简单代码,比针对特定处理器高度调整的代码更容易向量化。
在ARM编译器工具链中启用自动向量化
DS-5™ Professional中的ARM编译器工具链包括对向量化编译器的支持。要启用自动向量化,您必须针对具有NEON单元的处理器。所需的命令行选项是:
- --vectorize 启用向量化
- --cpu 7-A 或 --cpu Cortex-A8 指定具有NEON支持的核心或架构
- -O2 或 –O3 选择高级或积极的优化
- -Otime 优化速度而不是空间。
使用armcc命令行参数--remarks提供更多关于执行的优化信息,或者编译器无法执行某些优化的问题。
在GCC编译器中启用自动向量化
要在GCC中启用自动向量化,请使用命令行选项:
- -ftree-vectorize
- –mfpu=neon
- -mcpu 指定核心或架构。
在优化级别-O3下编译意味着-ftree-vectorize。
如果您没有指定-mcpu选项,那么GCC将使用其内置的默认核心。结果代码可能会运行得很慢,或者根本不运行。
-ftree-vectorize选项适用于许多支持SIMD操作的架构。
在裸机应用中启用NEON单元
裸机应用是一种直接在硬件上运行,没有内核或操作系统支持的应用。 默认情况下,在复位时NEON单元是禁用的,所以对于需要NEON指令的裸机应用,您必须手动启用它。EnableNEON
代码片段显示了如何手动启用NEON单元。
#include <stdio.h>
// 最基础的启动代码以运行NEON代码
__asm void EnableNEON(void)
{
MRC p15,0,r0,c1,c0,2 // 读取CP访问寄存器
ORR r0,r0,#0x00f00000 // 通过启用对协处理器10和11的访问来启用对NEON/VFP的完全访问
MCR p15,0,r0,c1,c0,2 // 写入CP访问寄存器
ISB
MOV r0,#0x40000000 // 打开VFP和NEON硬件
MSR FPEXC,r0 // 在FPEXC中设置EN位
}
当为带有NEON单元的处理器编译裸机应用时,编译器可能会使用NEON指令。例如,ARM编译器工具链的armcc
默认使用-O2优化,如果指定了-Otime和--vectorize选项,它会尝试为带有NEON单元的处理器向量化代码。 您可以这样编译裸机应用hello.c
:
armcc -c --cpu=Cortex-A8 --debug hello.c -o hello.o
armlink --entry=EnableNEON hello.o -o hello.axf