ARM平台NEON指令的编译和优化
式下使能NEON
#include
// Bare-minimum start-up code to run NEON code
__asm void EnableNEON(void)
{
MRC p15,0,r0,c1,c0,2 // Read CP Access register
ORR r0,r0,#0x00f00000 // Enable full access to NEON/VFP by enabling access to
// Coprocessors 10 and 11
MCR p15,0,r0,c1,c0,2 // Write CP Access register
ISB
MOV r0,#0x40000000 // Switch on the VFP and NEON hardware
MSR FPEXC,r0 // Set EN bit in FPEXC
}
下面的EnableNEON函数使能NEON协处理器;使用下面的编译选择就能在bare-metal下使能NEON
armcc -c --cpu=Cortex-A8 --debug hello.c -o hello.o
armlink --entry=EnableNEON hello.o -o hello.axf
系统运行时使能NEON
内核在遇到第一个NEON指令时会产生一个Undefined Instruction的异常,这会让内核自动重启NEON协处理器,内核还可以在上下文切换时关闭NEON来省电。
Linux内核的NEON配置

图1. NEON的Linux内核配置
使能NEON,需要选择
Floating point emulation→VFP-format floating point maths
和Floating point emulation→Advanced SIMD (NEON) Extension
检查Linux的配置文件来确认内核是否使能NEON
zcat /proc/config.gz | grep NEON
看是否存在
CONFIG_NEON=y
确认处理器是否支持NEON
cat /proc/cpuinfo | grep neon
看是否有如下内容
Features : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt
向量化NEON优化指南
避免指针混叠alias
C90不要求指针位置,不同指针可以指向相同的内存区域,C99中引入了__restrict关键字来表明只有这个指针能指向它工作的区域。
告诉编译器循环信息
如循环是否某个整数的整数倍,以方便向量化;如下表明循环次数是4的整数倍:
for(i=0 ; i < (len & ~3) ; i++)
{
。。。
}
for (i=0; i<(items*4); i+=1)
{
。。。
}
循环展开
#pragma unroll (n)
采用NEON Intrinsics
armcc, GCC/g++和llvm等编译器都支持 NEON C/C++ intrinsics,并且采用相同的语法规范。因而代码可以在各个编译器间共享。NEON Intrinsics的代码容易维护而且效率高。NEON Intrinsics采用新的数据类型,这些类型对应于D和Q寄存器。NEON Intrinsics写起来像是函数调用但对应于每一条NEON指令。编程NEON Intrinsics时不用考虑具体的寄存器分配和代码的schedule,pipeline流水安排等。但NEON Intrinsics往往不能产生想象的代码,性能上相比纯汇编要稍差一些。
减少循环内的相关性
如果当前迭代时使用的数据是上次迭代计算的结果,就产生了迭代间的相关性,可以拆分循环来减少相关。
向量化其他准则
- 短小的循环更容易让编译器实现自动向量化;
- 避免在循环内使用break退出循环
- 避免在循环内使用过多的条件语句,减少可能产生的条件跳转;
- 让循环次数尽可能是2的幂次
- 让编译器知晓循环次数,减少对循环次数为0等的判断;
- 循环内调用的函数尽量inline内联
- 使用数组+索引的方式访问比指针形式更容易向量化;
- 间接寻址(多重索引)不会向量化;
- 使用restrict关键字来告诉编译器没有重叠的内存区域;
总结
本文介绍了ARM平台基于ARM v7-A架构的ARM Cortex-A系列处理器(Cortex-A5, Cortex-A7, Cortex-A8, Cortex-A9, Cortex-A15)上的NEON多媒体处理硬件加速器针对C/C++语言、汇编语言和NEON intrinsics如何编译和优化,包含如何向量化、向量化的ARMCC和GCC编译器选项、NEON的汇编和EABI程序调用规范、如何在bare-metal和Linux操作系统上检测NEON硬件、如何指导编译器进行向量化NEON指令的优化等内容。
参考
http://houh-1984.blog.163.com/
本文介绍了ARM平台基于ARM v7-A架构的ARM Cortex-A系列处理器(Cortex-A5, Cortex-A7, Cortex-A8, Cortex-A9, Cortex-A15)上的NEON多媒体处理硬件加速器针对C/C++语言、汇编语言和NEON intrinsics如何编译和优化,包含如何向量化、向量化的ARMCC和GCC编译器选项、NEON的汇编和EABI程序调用规范、如何在bare-metal和Linux操作系统上检测NEON硬件、如何指导编译器进行向量化NEON指令的优化等内容。
ARM平台NEON指令编译和优 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)
