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正告

参考

  1. Profile guided optimization for native Android applications
  2. 应用配置文件疏导的优化 (PGO)
  3. How to compile with Profile Guided Optimization (PGO)