使用配置文件引导优化(PGO)

原文:https://source.android.com/devices/tech/perf/pgo

Android编译系统支持在具有blueprint构建规则的Android native 模块上使用Clang的配置文件引导优化(PGO)。本文描述Clang PGO如何持续生成和更新用于PGO的配置文件,以及如何将PGO与编译系统集成(使用用例)。

关于Clang PGO

Clang可以使用两种类型的配置文件执行配置文件引导优化:

  • 基于检测的配置文件是从检测的目标程序生成的。这些配置文件很详细,并且会产生高运行时开销。
  • 基于采样的配置文件通常通过采样硬件计数器来生成。它们会产生低运行时开销,并且无需对二进制文件进行任何检测或修改即可收集。它们没有基于检测的配置文件详细。

所有配置文件应该从应用程序的典型行为的代表性工作负载生成。虽然Clang同时支持基于AST的(-fprofile-instr-generate)和基于LLVM IR的(-fprofile-generate),Android仅支持基于LLVM IR的基于检测的PGO。

构建配置文件集合需要以下标志:

  • -fprofile-generate用于基于IR的仪器。使用此选项,后端使用加权最小生成树方法来减少检测点的数量并优化它们在低权重边缘的位置(对于链接步骤也使用此选项)。Clang驱动程序自动将运行时配置(libclang_rt.profile-*arch*-android.a)传递给链接器。该库包含在程序退出时将配置文件写入磁盘的例程。
  • -gline-tables-only 用于基于采样的配置文件收集,以生成最少的调试信息

配置文件可使用-fprofile-instr-use=*pathname*-fprofile-instr-use=*pathname*来用于PGO,分别对应基于检测的配置文件和基于采样的配置文件。

注:当对代码进行更改时,如果Clang无法再使用配置文件数据,则会生成 -Wprofile-instr-out-of-date警告。

使用PGO

使用PGO涉及以下步骤:

  1. 通过传递-fprofile-generate给编译器和链接器来构建带有检测的库/可执行文件 。
  2. 通过在检测二进制文件上运行代表性工作负载来收集配置文件
  3. 使用该llvm-profdata实用程序对配置文件进行后处理(有关详细信息,请参阅处理LLVM配置文件)。
  4. 通过传递-fprofile-use=<>.profdata给编译器和链接器来将配置文件应用于PGO 。

对于Android中的PGO,应该离线收集配置文件并与代码一起检查以确保可重现的构建。配置文件可以用作代码演变,但必须定期重新生成(或者每当Clang警告配置文件是陈旧的时)。

收集配置文件

Clang可以使用通过运行基准测试收集的配置文件,使用库的检测构建,或者在运行基准测试时通过采样硬件计数器。目前,Android不支持使用基于采样的配置文件集合,因此您必须使用经过检测的构建来收集配置文件:

  1. 确定基准和由该基准共同行使的一组库。
  2. 添加pgo属性到基准和库(详细信息如下)。
  3. 使用以下方法生成带有这些库的检测副本的Android构建:
make ANDROID_PGO_INSTRUMENT=benchmark

*benchmark*是一个占位符,用于标识在构建期间检测的库集合。实际的代表性输入(以及可能与被基准测试的库链接的另一个可执行文件)并非特定于PGO,超出了本文档的范围。

  1. 在设备上Flash或同步已检测的构建。
  2. 运行基准测试以收集配置文件。
  3. 使用该llvm-profdata工具(下面讨论)对配置文件进行后处理,并准备好将其签入源树。

在构建期间使用配置

在Android树中检查配置文件toolchain/pgo-profiles。该名称应与库profile_filepgo属性的子属性中指定的名称匹配 。构建库时,构建系统会自动将配置文件传递给Clang。该ANDROID_PGO_DISABLE_PROFILE_USE 环境变量可以被设置为true来暂时禁用PGO和衡量其性能优势。

要指定其他特定于产品的配置文件目录,请将它们附加到BoardConfig.mk里的make变量PGO_ADDITIONAL_PROFILE_DIRECTORIES中。如果指定其他路径,这些路径配置文件覆盖在toolchain/pgo-profiles中的路径。

使用dist目标来make生成发布映像时,构建系统会将缺失的配置文件的名称写入$DIST_DIR/pgo_profile_file_missing.txt。您可以检查此文件以查看意外删除的配置文件(静默禁用PGO)。

在Android.bp文件中启用PGO

要在Android.bp文件中为native 模块启用PGO ,只需指定pgo属性即可。此属性具有以下子属性:

属性 描述
instrumentation PGO使用检测则设置为true。默认是 false
sampling 目前不受支持。PGO使用采样设置为true。默认是false
benchmarks 字符串列表。如果在ANDROID_PGO_INSTRUMENT构建选项中指定了列表中的任何基准,则构建此模块用于分析。
profile_file 用于PGO的配置文件(相对于toolchain/pgo-profile)。构建通过添加此文件至$DIST_DIR/pgo_profile_file_missing.txt 来警告此文件不存在,除非enable_profile_use属性设置为false ANDROID_PGO_NO_PROFILE_USE构建变量设置为true
enable_profile_use 若在构建期间不应使用配置文件则设置为false。可以在引导期间使用以启用配置文件收集或暂时禁用PGO。默认是true
cflags 在检测的构建期间使用的其他标志的列表。

带PGO的模块示例:

cc_library {
    name: "libexample",
    srcs: [
        "src1.cpp",
        "src2.cpp",
    ],
    static: [
        "libstatic1",
        "libstatic2",
    ],
    shared: [
        "libshared1",
    ]
    pgo: {
        instrumentation: true,
        benchmarks: [
            "benchmark1",
            "benchmark2",
        ],
        profile_file: "example.profdata",
    }
}

如果基准benchmark1和benchmark2 行使代表行为库libstatic1, libstatic2或者libshared1,则这些库的pgo属性也包含基准。Android.bp中的defaults模块可include一个一系列库的共通pgo定义,以避免多个模块重复相同的构建规则。

为一个架构选择不同的配置文件或选择性地禁用PGO,需要指定每个体系结构的profile_file, enable_profile_use以及cflags属性。例如(架构目标以粗体显示):

cc_library {
    name: "libexample",
    srcs: [
          "src1.cpp",
          "src2.cpp",
    ],
    static: [
          "libstatic1",
          "libstatic2",
    ],
    shared: [
          "libshared1",
    ],
    pgo: {
         instrumentation: true,
         benchmarks: [
              "benchmark1",
              "benchmark2",
         ],
    }

    target: {
         android_arm: {
              pgo: {
                   profile_file: "example_arm.profdata",
              }
         },
         android_arm64: {
              pgo: {
                   profile_file: "example_arm64.profdata",
              }
         }
    }
}

要在基于检测的分析期间解析对分析运行时库的引用,请将构建标志 -fprofile-generate传递给链接器。使用PGO检测的静态库,所有共享库以及直接依赖于静态库的任何二进制文件也必须为PGO进行检测。但是,此类共享库或可执行文件不需要使用PGO配置文件,并且其enable_profile_use属性可以被设置为false。除此限制外,您可以将PGO应用于任何静态库,共享库或可执行文件。

处理LLVM配置文件

执行一个检测库或可执行文件在/data/local/tmp中生成一个名为default_*unique_id*_0.profraw的配置文件 (其中unique_id是此库唯一的数字哈希值)。如果此文件已存在,则分析运行时会在编写配置文件时将新配置文件与旧配置文件合并。要更改配置文件的位置,请在运行时设置LLVM_PROFILE_FILE环境变量。

[llvm-profdata](https://llvm.org/docs/CommandGuide/llvm-profdata.html)实用程序用于将.profraw文件(并可能合并多个.profraw文件)转换为.profdata 文件:

llvm-profdata merge -output=profile.profdata <.profraw and/or .profdata files>

然后*profile.profdata* 可被签入源码树以便在构建时使用。

如果在基准测试期间加载了多个检测二进制文件/库,则每个库都会生成一个具有唯一ID 的独立.profraw文件。通常,所有这些文件都可以合并为单个 .profdata文件并用于PGO构建。如果库由另一个基准测试执行,则必须使用两个基准测试的配置文件优化该库。在这种情况下,show 选项llvm-profdata是有用的:

llvm-profdata merge -output=default_unique_id.profdata default_unique_id_0.profraw
llvm-profdata show -all-functions default_unique_id.profdata

要将unique_id映射到单个库,请在每个unique_idshow输出中搜索该库唯一的函数名称。

案例研究:ART的PGO

案例研究将ART作为一个相关的例子; 但是,它并不能准确描述为ART或其相互依赖性分析的实际库集。

ART中的dex2oat预编译器依赖于 libart-compiler.so,而后者依赖于 libart.so。ART运行时主要在 libart.so中实现。编译器和运行时的基准将是不同的:

基准 配置库
dex2oat dex2oat(可执行), libart-compiler.solibart.so
art_runtime libart.so
  1. 将以下pgo属性添加到dex2oatlibart-compiler.so
    pgo: {
        instrumentation: true,
        benchmarks: ["dex2oat",],
        profile_file: "dex2oat.profdata",
    }
  1. 将以下pgo属性添加到libart.so
    pgo: {
        instrumentation: true,
        benchmarks: ["art_runtime", "dex2oat",],
        profile_file: "libart.profdata",
    }
  1. 使用以下方法为dex2oatart_runtime基准创建检测构建:
    make ANDROID_PGO_INSTRUMENT=dex2oat
    make ANDROID_PGO_INSTRUMENT=art_runtime

或者,使用以下方法创建一个具有所有库检测的单个检测构建:

    make ANDROID_PGO_INSTRUMENT=dex2oat,art_runtime
    (or)
    make ANDROID_PGO_INSTRUMENT=ALL

第二个命令构建所有启用PGO的模块以进行性能分析。

  1. 运行基准测试dex2oatart_runtime以获得:
    • 来自dex2oatdex2oat_exe.profdatadex2oat_libart-compiler.profdatadexeoat_libart.profdata)的三个.profraw文件,使用处理LLVM配置文件中描述的方法进行标识。
    • 单个art_runtime_libart.profdata文件。
  2. dex2oat可执行文件和 libart-compiler.so使用生成一个通用的profdata文件:
llvm-profdata merge -output=dex2oat.profdata \
    dex2oat_exe.profdata dex2oat_libart-compiler.profdata
  1. 通过合并两个基准测试中的配置文件来获取libart.so的配置文件:
llvm-profdata merge -output=libart.profdata \
    dex2oat_libart.profdata art_runtime_libart.profdata

libart.so的两个配置文件的原始计数可能是不同的,因为基准测试用例的数量和运行的持续时间不同。在这种情况下,您可以使用加权合并:

llvm-profdata merge -output=libart.profdata \
    -weighted-input=2,dex2oat_libart.profdata \
    -weighted-input=1,art_runtime_libart.profdata

上面的命令为 dex2oat配置文件赋予两倍的权重。实际权值应根据域知识或实验确定。

  1. dex2oat.profdatalibart.profdata配置文件签入到toolchain/pgo-profiles以便构建时使用。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容

  • LLVM 简介 LLVM 全称是 Low Level Virtual Machine,它是源自 the Unive...
    juniway阅读 36,826评论 0 21
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 31,790评论 2 89
  • mean to add the formatted="false" attribute?.[ 46% 47325/...
    ProZoom阅读 2,615评论 0 3
  • 本周,我完成了: 1、四五周的数学讨论 2、英语趣配音 3、看了《我们的小狼朋...
    梁朵阅读 164评论 0 1