产品资讯

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

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

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

什么是 AutoFDO?

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

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

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

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

现实世界中的性能优势

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

最明显的改进如下所示。如需详细了解这些内核版本的 AutoFDO 配置文件,请参阅 android16-6.12 和 android15-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.12 和 android15-6.6 分支中部署 AutoFDO。除了此次初始推出之外,我们还看到了几个有前景的途径来进一步增强这项技术:

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

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

继续阅读