gcc编译时指定CPU架构可提高程序运行速度
在ARMv7设备上效果尤为显著。
ARM的指令集版本很多,对性能影响较大的部分一直到ARMv8才大致统一。现在ARM的32位设备为了较好的兼容性,会使用不带硬件浮点处理器的ARMv4为基准,但为了提高性能,许多linux发行版还会提供针对带硬件浮点的armhf(ARM Hard Float)进行预编译的软件包。
这里以一块CortexA7的开发板为例,说明指定CPU架构可以对软件性能产生多大的提升。
准备一个简单的测试程序:
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
int check(int n)
{
int i;
for(i=2;i<=n/2+1;i++)
if(n%i==0)
return(1);
return(0);
}
int main(int argc, char *argv[])
{
int n1=0,n2=0,i,c=0;
if(argc==3)
{
n1=atoi(argv[1]);
n2=atoi(argv[2]);
}
if(n2>n1 && n1>=3 && n2>=3)
printf("Begin:%d End:%d\n",n1,n2);
else
{
printf("Begin:3 End:100000\n");
n1=3;
n2=100000;
}
for(i=n1;i<=n2;i++)
c+=check(i);
printf("Finished, c=%d\n",c);
return(0);
}
测试环境为Armbian Stretch with Linux 5.5.0-rc6-sunxi (Debian 9),gcc版本为6.3.0,使用系统自带的time命令对程序运行时间进行测量。
首先是关闭gcc优化的(优化等级-O0),测试结果为:
优化等级-O0
real 0m15.806s
user 0m15.793s
sys 0m0.008s
接着把gcc优化完全打开(优化等级-O3),测试结果为:
优化等级-O3
real 0m13.081s
user 0m13.062s
sys 0m0.012s
相比之前有了接近3秒的提升。
gcc中,使用-mcpu可以指定目标处理器架构,如此处,在编译时附加参数-mcpu=cortex-a7,同样将gcc优化完全打开,测试结果为:
优化等级-O3 指定CPU架构
real 0m2.962s
user 0m2.960s
sys 0m0.002s
效果提升非常显著。
在指定了处理器架构时,gcc会针对相应的架构在指令集层面对其进行优化,使得生成的程序对相应CPU架构的分支预测器、扩展指令等及其友好,从而显著提高了程序的执行速度,但同时这也会在一定程度上牺牲兼容性。此处将指定了处理器架构的程序放到树莓派zero上运行时,由于树莓派zero的指令集为ARMv6,运行时会报Illegal Instruction的错误,提示程序中包含非法指令集。
所以,如果使用源码编译给本机安装的程序,通过指定CPU架构可以显著提高程序运行速度。如果编译的程序需要发布给其他设备使用,则需要考虑设备间的兼容性问题。