产品资讯

提升 Android 性能:为内核引入 AutoFDO

阅读用时:4 分钟
Yabin Cui
软件工程师

我们是 Android LLVM 工具链团队。我们的首要任务之一是通过 LLVM 生态系统中的优化技术来提升 Android 性能。我们一直在寻找让 Android 运行得更快、更顺畅、更高效的方法。虽然我们的大部分优化工作都在用户空间中进行,但内核仍然是系统的核心。今天,我们很高兴地宣布,我们正在将自动反馈导向优化 (AutoFDO) 引入 Android 内核,从而为用户带来显著的性能提升。

什么是 AutoFDO?

在标准软件构建过程中,编译器会根据静态代码提示做出数千个小决策,例如是否内联函数以及可能会采用哪个条件分支。虽然这些启发式方法很有用,但它们并不总是能准确预测真实手机使用过程中的代码执行情况。

AutoFDO 通过使用实际执行模式来指导编译器,从而改变了这种情况。这些模式代表了代码在实际使用过程中最常见的指令执行路径,是通过记录 CPU 的分支历史记录来捕获的。虽然这些数据可以从舰队设备中收集,但对于内核,我们会在实验室环境中使用代表性工作负载(例如运行最热门的 100 个应用)来合成这些数据。我们使用抽样分析器来捕获这些数据,以确定代码的哪些部分是“热门”(经常使用)部分,哪些部分是“冷门”部分。当我们使用这些配置文件重新构建内核时,编译器可以做出更智能的优化决策,这些决策是根据实际 Android 工作负载量身定制的。

为了解此优化的影响,请考虑以下关键事实:

  • 在 Android 上,内核约占 CPU 时间的 40%。
  • 我们已使用 AutoFDO 来优化用户空间中的原生可执行文件和库,从而将冷启动应用速度提高了约 4%,并将启动时间缩短了 1%。

现实世界中的性能优势

通过利用受控实验环境中的配置文件,我们发现关键 Android 指标有了显著改进。这些配置文件是通过应用爬取和启动收集的,并在 Pixel 设备上针对 6.1、6.6 和 6.12 内核进行了衡量。

最明显的改进如下所列。如需详细了解这些内核版本的 AutoFDO 配置文件,请参阅 android16-6.12android15-6.6 内核各自的 Android 内核代码库。

boosting_2.png

这些不仅仅是理论上的数字。这可带来更流畅的界面、更快的应用切换速度、更长的电池续航时间,并让最终用户获得整体上响应更快的设备。

运作方式:流水线

我们的部署策略涉及复杂的流水线,以确保个人资料保持相关性,并确保效果保持稳定。

boosting_3.png

第 1 步:收集个人资料

虽然我们依靠内部测试设备群来分析用户空间二进制文件,但我们已改用受控的实验室环境来分析通用内核映像 (GKI)。将分析与设备发布周期分离,可实现灵活、即时的更新,而无需考虑已部署的内核版本。至关重要的是,测试证实,这种基于实验室的数据可带来与真实设备群相当的性能提升。

  • 工具和环境:我们使用最新的内核映像刷写测试设备,并使用 simpleperf 捕获指令执行流。此过程依赖于硬件功能来记录分支历史记录,具体来说,是在 Pixel 设备上利用  ARM 嵌入式跟踪扩展 (ETE)ARM 跟踪缓冲区扩展 (TRBE)
  • 工作负载:我们使用 Android 应用兼容性测试套件 (C-Suite) 中最热门的 100 个应用构建了一个具有代表性的工作负载。为了捕获最准确的数据,我们重点关注:
    • 应用启动:针对最明显的用户延迟进行优化
    • AI 驱动的应用爬取:模拟连续不断的用户互动
    • 系统级监控:不仅捕获前台应用活动,还捕获关键的后台工作负载和进程间通信
  • 验证:此合成工作负载与从内部队列收集的执行模式的相似度为 85%
  • 目标数据:通过充分重复这些测试,我们可以捕获高保真执行模式,准确反映真实世界中用户与最热门应用的互动情况。此外,借助这种可扩展的框架,我们可以无缝集成其他工作负载和基准,从而扩大覆盖范围。

第 2 步:个人资料处理

我们会对原始轨迹数据进行后处理,以确保其干净、有效且可供编译器使用。

  • 汇总:我们将多次测试运行和多个设备的数据整合到单个系统视图中。
  • 转换: 我们转换原始轨迹,使其符合 AutoFDO 配置文件格式,并根据需要过滤掉不需要的符号。
  • 配置文件精简:我们会精简配置文件,移除“冷”函数的数据,以便这些函数使用标准优化。这样可以防止很少使用的代码出现回归,并避免二进制文件大小不必要地增加。

第 3 步:个人资料测试

在部署之前,系统会对配置文件进行严格验证,以确保它们能够带来稳定的性能提升,而不会带来稳定性风险。

  • 配置文件和二进制文件分析:我们会严格比较新配置文件的内容(包括热门函数、样本数量和配置文件大小)与之前版本的内容。我们还使用该配置文件构建新的内核映像,并分析二进制文件以确保对文本部分的更改符合预期。
  • 性能验证:我们针对新的内核映像运行有针对性的基准测试。这可确认新的内核映像是否保持了之前基准确立的性能改进。

持续更新

代码会随着时间的推移自然而然地“漂移”,因此静态配置文件最终会失去效用。为了保持最佳性能,我们会持续运行流水线,以推动定期更新:

  • 定期刷新:我们在每个 GKI 版本发布之前刷新 Android 内核 LTS 分支中的配置文件,确保每个 build 都包含最新的配置文件数据。
  • 未来扩展:我们目前正在向 android16-6.12android15-6.6 分支提供这些更新,并将支持范围扩大到更新的 GKI 版本,例如即将推出的 android17-6.18

确保稳定性

在采用基于配置的优化时,一个常见的问题是它是否会带来稳定性风险。由于 AutoFDO 主要影响编译器启发式方法(例如函数内联和代码布局),而不是改变源代码的逻辑,因此它可保持内核的功能完整性。这项技术已在大规模应用中得到验证,多年来一直作为 Android 平台库、ChromeOS 和 Google 自身服务器基础设施的标准优化方法。

为了进一步保证行为的一致性,我们应用了“默认保守”策略。未在高保真度配置文件中捕获的函数将使用标准编译器方法进行优化。这可确保内核的“冷”或很少执行的部分的行为与标准 build 中的行为完全相同,从而防止在极端情况下出现性能退化或意外行为。

展望未来

我们目前正在 android16-6.12android15-6.6 分支中部署 AutoFDO。除了这项初步部署之外,我们还看到了几个有前景的途径来进一步增强这项技术:

  • 扩大覆盖面:我们期待将 AutoFDO 配置文件部署到更新的 GKI 内核版本和当前 aarch64 支持范围之外的其他 build 目标。
  • GKI 模块优化:目前,我们的优化主要集中在主内核二进制文件 (vmlinux) 上。将 AutoFDO 扩展到 GKI 模块可以为内核子系统的更大部分带来性能优势。
  • 供应商模块支持:我们还希望支持使用驱动程序开发套件 (DDK) 构建的供应商模块的 AutoFDO。我们的构建系统 (Kleaf) 和性能剖析工具 (simpleperf) 已经支持这些功能,因此供应商可以将这些相同的优化技术应用于其特定的硬件驱动程序。
  • 更广泛的配置文件覆盖面:有可能从更广泛的关键用户历程 (CUJ) 中收集配置文件,以便对其进行优化。

通过将 AutoFDO 引入 Android 内核,我们确保操作系统最基础的部分能够根据您日常使用设备的方式进行优化。

继续阅读