PGO (Profile Guided Optimization)
是指利用程序运行过程中采集到的 profile 数据,来重新编译程序以达到优化效果的 post-link 优化技术。其原理认为,对于特征相似的 input,程序运行的特征也相似,因此,我们可以把运行期的 profile 特征数据先采集一遍,再用来指导编译过程进行优化。
方案实施
方案一:
- 添加编译参数:
-fprofile-instr-generate
完整编译项目 - 启动项目进程,像平常一样运行程序,尽可能多覆盖常用的功能点。会自动在当前目录生成
default.profraw
文件 - 执行命令
llvm-profdata merge -output=profile.profdata default.profraw
将采样文件转化成llvm编译认识的指导文件。程序每次运行都会生成新的profraw
文件,如果不指定名称会覆盖上次的default.profraw
,可以使用环境变量LLVM_PROFILE_FILE=${WOKR_DIR}/${PROGRAM_NAME}.profraw
来指定生成的文件名,然后执行llvm-profdata merge -output=profile.profdata *.profraw
来生成profdata文件 - 移除参数
-fprofile-instr-generate
,添加参数-fprofile-instr-use=${WORK_DIR}/profile.profdata
重新编译项目源码 - 运行程序执行相同的操作,验证效率优化的结果。
方案二:
此方案需要CPU支持IBS
- 添加编译参数:
-funique-internal-linkage-names
-fdebug-info-for-profiling
,添加链接参数-Wl,--no-rosegment
编译项目源码(-funique-internal-linkage-names
clang9不支持,这里升级到了clang15) - 启动项目进程。
- 利用perf工具对程序进行采样,运行
perf record -p <pid> -e cycles:up -j any,u -a -- sleep 60
,在此期间点击程序常用操作和功能。生成perf.data
文件 - 执行
create_llvm_prof --profile perf.data --binary <运行的可执行程序> --out=llvm.prof
生成llvm.prof
编译指导文件 - 去掉之前的编译参数,加上编译参数
-fprofile-sample-use=llvm.prof
重新编译项目源码 - 运行程序执行相同的操作,验证效率优化的结果。
参考资料
- https://blog.csdn.net/ByteDanceTech/article/details/124030419
- https://source.android.google.cn/docs/core/perf/pgo?hl=zh-cn
- https://www.xujun.org/note-157156.html
- https://blog.csdn.net/Rong_Toa/article/details/124604534