1 问题背景
项目中遇到鲲鹏芯片架构下编译C/C++代码编译时间过长,增加了业务版本CI时间,需要优化。本案例分享一下基于cmake和GCC编译优化的思路和措施。
2 原因分析
获取环境以后,利用开源软件A编译测试,逐步对可能影响编译时间的因素排查调优分析。
1. 充分发挥多CPU并行处理功能
Make阶段利用多线程处理,将进程个数设置成cpu的核数,提高编译速度。
效果:相对于单线程编译来说,有几倍提升。
2. 降低iowait
同过iostat观察,编译过程中有部分时间出现iowait,特别是编译写文件的时候。
方法:
修改缓存VM参数,增加缓冲:
以下参数和X86配置不一致,修改一致为:
(1)/proc/sys/vm/dirty_ratio 修改前10,修改后20
效果:
整体编译时间减少2s左右,说明有一定的效果,还不是关键因素。
3. 去掉nohz=off
/proc/cmdline如果存在nohz=off配置,会对系统性能有影响,尝试去掉测试性能
方法:
找到系统中/boot/efi/EFI/XXX/grub.cfg的nohz=off去掉,并重启服务器
效果:
去掉nohz=off参数后测试性能和修改前差不多
4. Gcc参数加入ARM相关编译参数
新版本gcc里面加入了对ARM架构的编译优化参数,如-mtune=tsv110,-march=armv8-a,尝试是否对编译性能有提升。
方法:
升级编译gcc到9.2.0版本,在编译脚本gcc后面加上-mtune=tsv110,-march=armv8-a参数,重新对程序进行编译测试性能。
效果:
添加参数后gcc编译性能无提升,平均执行时间和修改前差不多。此选项加入是优化编译软件运行性能的,不会降低编译时间。
5. 内存页大小
通过perf分析,编译代码有很多跳转指令,汇编代码中加载内存指令的执行时间段很高,分析可能是内存主要瓶颈。Perf热点函数分析内存换页函数调用频繁,浪费时间。可以通过扩大内存页来加大每页命中率,减少页切换的资源浪费。
方法:
获取内核源码,修改.config文件参数CONFIG_ARM64_64K_PAGES=y(注意,执行make menuconfig通过界面修改更为全面),重新编译内核,然后系统用新内核启动。
检查是否修改成功: getconf PAGESIZE 显示为65536 即表示修改成功。
效果:
编译时间缩短20%左右,优化效果较大。
3 解决方案
综上分析,通过并发编译、修改vm缓存参数和调整内存页大小为64K对编译时间优化有显著效果。修改方法也在上文有描述。
4 总结
优化编译时间在版本构建的时候很关键,能节约不少构建时间,提高生产效率。目前大多是对编译出程序性能的优化,这样必然会增加编译时间,比如说如果用高版本的GCC编译器,编译出来的程序性能会更好,但是编译时间可能变长了,相比低版本的GCC来说。也就是说,如果想优化编译时间,尽量避免去用新GCC版本,或者利用新的GCC编译优化参数。
提供程序运行性能,让他跑得更快,还是老一套,去分析程序运行时的系统瓶颈,解除瓶颈后会对性能有提升,如本案例中内存就是一个瓶颈。
1 问题背景
项目中遇到鲲鹏芯片架构下编译C/C++代码编译时间过长,增加了业务版本CI时间,需要优化。本案例分享一下基于cmake和GCC编译优化的思路和措施。
2 原因分析
获取环境以后,利用开源软件A编译测试,逐步对可能影响编译时间的因素排查调优分析。
1. 充分发挥多CPU并行处理功能
Make阶段利用多线程处理,将进程个数设置成cpu的核数,提高编译速度。
效果:相对于单线程编译来说,有几倍提升。
2. 降低iowait
同过iostat观察,编译过程中有部分时间出现iowait,特别是编译写文件的时候。
方法:
修改缓存VM参数,增加缓冲:
以下参数和X86配置不一致,修改一致为:
(1)/proc/sys/vm/dirty_ratio 修改前10,修改后20
效果:
整体编译时间减少2s左右,说明有一定的效果,还不是关键因素。
3. 去掉nohz=off
/proc/cmdline如果存在nohz=off配置,会对系统性能有影响,尝试去掉测试性能
方法:
找到系统中/boot/efi/EFI/XXX/grub.cfg的nohz=off去掉,并重启服务器
效果:
去掉nohz=off参数后测试性能和修改前差不多
4. Gcc参数加入ARM相关编译参数
新版本gcc里面加入了对ARM架构的编译优化参数,如-mtune=tsv110,-march=armv8-a,尝试是否对编译性能有提升。
方法:
升级编译gcc到9.2.0版本,在编译脚本gcc后面加上-mtune=tsv110,-march=armv8-a参数,重新对程序进行编译测试性能。
效果:
添加参数后gcc编译性能无提升,平均执行时间和修改前差不多。此选项加入是优化编译软件运行性能的,不会降低编译时间。
5. 内存页大小
通过perf分析,编译代码有很多跳转指令,汇编代码中加载内存指令的执行时间段很高,分析可能是内存主要瓶颈。Perf热点函数分析内存换页函数调用频繁,浪费时间。可以通过扩大内存页来加大每页命中率,减少页切换的资源浪费。
方法:
获取内核源码,修改.config文件参数CONFIG_ARM64_64K_PAGES=y(注意,执行make menuconfig通过界面修改更为全面),重新编译内核,然后系统用新内核启动。
检查是否修改成功: getconf PAGESIZE 显示为65536 即表示修改成功。
效果:
编译时间缩短20%左右,优化效果较大。
3 解决方案
综上分析,通过并发编译、修改vm缓存参数和调整内存页大小为64K对编译时间优化有显著效果。修改方法也在上文有描述。
4 总结
优化编译时间在版本构建的时候很关键,能节约不少构建时间,提高生产效率。目前大多是对编译出程序性能的优化,这样必然会增加编译时间,比如说如果用高版本的GCC编译器,编译出来的程序性能会更好,但是编译时间可能变长了,相比低版本的GCC来说。也就是说,如果想优化编译时间,尽量避免去用新GCC版本,或者利用新的GCC编译优化参数。
提供程序运行性能,让他跑得更快,还是老一套,去分析程序运行时的系统瓶颈,解除瓶颈后会对性能有提升,如本案例中内存就是一个瓶颈。