产品动态

提升 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 分支 中的配置文件,确保每个构建都包含最新的配置文件数据。
  • 未来扩展: 我们目前正在向 android16-6.12android15-6.6 分支提供这些更新,并将支持扩展到更新的 GKI 版本,例如即将推出的 android17-6.18

确保稳定性

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

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

展望未来

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

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

通过将 AutoFDO 引入 Android 内核,我们确保操作系统的基础针对您每天使用设备的方式进行了优化。

继续阅读