注:这些东西未验证是否正确
交叉编译加入如下命令:
--vectorize Enable vectorization--cpu=Cortex-A8 Specify a core or architecture with NEON support
-O2 or –O3 Select high level or aggressive optimization
-Otime Optimize for speed rather than for space.
--remarks 使用这个命令后,编译器会输出一些信息,如:是什么原因阻止了代码的矢量化优化。
为指针添加__restrict,(但必须要保证确实没有指针访问区域重叠的现象,否则结果会出错);
使用自然类型;
将组合的数组分割为几个独立的数组;
简单的代码编译器更容易理解与自动优化;
在循环中调用的函数应该声明为内联函数;
使用数组索引比使用指针好;
循环次数在已知时要直接传递常数,而不要用变量;
或者循环次数是2的倍数时,需要告诉编译器;
如:
int accumulate(int * c, int len)
{
int i, retval;
for(i = 0, retval = 0; i < (len & ~3) ; i++)//告诉编译器len是4的整数倍,这样编译器能更好的优化代码
{
retval = retval + c[i]
}
return retval;
}
或者
int accumulate(int * c, int len_div_4)
{
int i, retval;
for(i = 0, retval = 0; i < (len_div_4 * 4) ; i++)//告诉编译器len是4的整数倍,这样编译器能更好的优化代码
{
retval = retval + c[i]
}
return retval;
}
避免循环依赖(即某次循环的结果会被前一次循环的结果影响);
避免在循环中出现条件判断;
在没有SIMD时,使用32bit类型会更好。但在矢量化时,使用尽可能小的数据类型会更好,这样neon寄存器一次能处理更多数据;
在不需要的情况下避免使用64bit的数据类型(long long或者double float)。这种类型会阻止编译器做矢量化;
浮点操作矢量化可导致精度的丢失,所以默认情况下浮点操作不会矢量化。如果算法不要求太高精度,在armcc中可通过--fpmode=fast命令行来使能浮点矢量化优化(GCC是-ffast-math)。(neon的浮点精度并不完全符合IEEE754标准,默认情况下,armcc使用--fpmode=std来允许这个误差。然而如果是通过--fpmode=ieee_full来指明一定要符合IEEE754标准,则大多数浮点操作不能被矢量化优化。);