Android应用PGO优化native库运行速度
Profile-guided optimization (PGO),配置文件疏导的优化,基于插桩或采样从程序运行时生成配置文件,使编译器对内联和代码布局做优化,能够取得收费的性能晋升。在安卓中应用的教程较少,实际操作时会遇到一些问题,在这里记录一下应用插桩的形式。
1. 应用-fprofile-generate
编译和链接通过插桩的动静库
增加编译参数
android { ... defaultConfig { ... externalNativeBuild { cmake { cppFlags '-std=c++11 -fprofile-generate' } } }}
2. 运行具备代表性的流程,收集配置文件
安卓中生成配置文件需在最初手动调用__llvm_profile_write_file
办法,在C++中须要增加extern "C"
,否则链接时会找不到此办法
extern "C" {extern int __llvm_profile_write_file(void);}
加载动静库前需设置环境变量 LLVM_PROFILE_FILE
指定配置文件生成地位
static { try { Os.setenv("LLVM_PROFILE_FILE", "/path/to/%m.profraw", true); } catch (ErrnoException e) { e.printStackTrace(); } System.loadLibrary("native-lib");}
LLVM_PROFILE_FILE
能够应用上面的修饰符来设置配置文件门路
- %p 过程ID
- %h hostname
- %m 惟一的配置文件名称
如果呈现以下谬误
java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "__start___llvm_prf_vnds" referenced by "... .so"
须要改链接程序为lld
或者gold
,ndk r22开始曾经默认应用lld
,也能够降级ndk到r22
android { ... ndkVersion '22.1.7171670'}
3. 应用llvm-profdata
合并转换配置文件
如果有多个配置文件,用上面的命令合并和转换
$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-profdata \ merge --output=pgo_profile.profdata \ <list-of-profraw-files>
即便只有一个配置文件也须要用此命令转换格局
4.应用配置文件编译
android { ... defaultConfig { ... externalNativeBuild { cmake { cppFlags '-std=c++11 -fprofile-use=/path/to/<>.profdata' } } }}
代码更改后也能够应用这个配置文件,如果无奈持续应用,编译器会生成 -Wprofile-instr-out-of-date
正告
参考
- Profile guided optimization for native Android applications
- 应用配置文件疏导的优化 (PGO)
- How to compile with Profile Guided Optimization (PGO)