プロダクト ニュース

Android のパフォーマンスを向上: カーネル向け AutoFDO の導入

4 分で読了
Yabin Cui
ソフトウェア エンジニア

Android LLVM ツールチェーン チームです。私たちの最優先事項の一つは、LLVM エコシステムの最適化手法を通じて Android のパフォーマンスを向上させることです。Android をより高速、スムーズ、効率的にする方法を常に探しています。最適化作業の多くはユーザー空間で行われますが、カーネルはシステムの中心です。今回は、Android カーネルに自動フィードバック指向最適化(AutoFDO)を導入し、ユーザーに大きなパフォーマンス向上をもたらす方法をご紹介します。

AutoFDO とは

標準的なソフトウェア ビルドでは、コンパイラは静的コードのヒントに基づいて、関数をインライン化するかどうか、条件分岐のどちらのブランチが選択される可能性が高いかなど、数千もの小さな判断を行います。このようなヒューリスティックは便利ですが、実際のスマートフォンの使用状況におけるコード実行を常に正確に予測できるとは限りません。

AutoFDO は、実際の実行パターンを使用してコンパイラをガイドすることで、この問題を解決します。これらのパターンは、実際の使用時にコードがたどる最も一般的な命令実行パスを表しており、CPU の分岐履歴を記録することで取得されます。このデータはフリート デバイスから収集できますが、カーネルの場合は、人気の高いアプリの上位 100 個を実行するなど、代表的なワークロードを使用してラボ環境で合成します。サンプリング プロファイラを使用してこのデータを取得し、コードのどの部分が「ホット」(頻繁に使用される)で、どの部分が「コールド」であるかを特定します。これらのプロファイルを使用してカーネルを再ビルドすると、コンパイラは実際の Android ワークロードに合わせて最適化された、よりスマートな判断を行うことができます。

この最適化の効果を理解するために、次の重要な事実を考慮してください。

  • Android では、カーネルが CPU 時間の約 40% を占めています。
  • AutoFDO を使用して、ユーザー空間のネイティブ実行可能ファイルとライブラリを最適化し、コールド アプリの起動を約 4% 改善し、起動時間を 1% 短縮しています。

実際のパフォーマンスの向上

管理されたラボ環境のプロファイルを利用することで、Android の主要な指標全体で目覚ましい改善が見られました。これらのプロファイルは、アプリのクロールと起動を使用して収集され、6.1、6.6、6.12 カーネルの Google Pixel デバイスで測定されました。

最も顕著な改善点は以下のとおりです。これらのカーネル バージョンの AutoFDO プロファイルの詳細については、android16-6.12 カーネルと android15-6.6 カーネルのそれぞれの Android カーネル リポジトリをご覧ください。

boosting_2.png

これらは単なる理論上の数値ではありません。インターフェースの操作性が向上し、アプリの切り替えが速くなり、バッテリー駆動時間が長くなり、エンドユーザーにとってデバイス全体の応答性が向上します。

仕組み: パイプライン

Google のデプロイ戦略では、プロファイルの関連性を維持し、パフォーマンスを安定させるために、高度なパイプラインを使用しています。

boosting_3.png

ステップ 1: プロファイルの収集

ユーザー空間バイナリのプロファイリングには内部テスト フリートを使用していますが、Generic Kernel Image(GKI)では管理されたラボ環境に移行しました。プロファイリングをデバイス リリース サイクルから切り離すことで、デプロイされたカーネル バージョンに関係なく、柔軟かつ迅速に更新できます。重要なことに、テストでは、このラボベースのデータが、実際のフリートからのデータと同程度のパフォーマンス向上をもたらすことが確認されています。

ステップ 2: プロファイルの処理

未加工のトレースデータを後処理して、クリーンで効果的で、コンパイラで使用できる状態にします。

  • 集計: 複数のテスト実行とデバイスからのデータを 1 つのシステムビューに統合します。
  • 変換: 未加工のトレースを AutoFDO プロファイル形式に変換し、必要に応じて不要なシンボルを除外します。
  • プロファイルのトリミング: プロファイルをトリミングして、「コールド」関数のデータを削除し、標準の最適化を使用できるようにします。これにより、使用頻度の低いコードでの回帰を防ぎ、バイナリサイズの不要な増加を回避できます。

ステップ 3: プロファイルのテスト

デプロイ前に、プロファイルに対して厳格な検証を行い、安定性のリスクなしに一貫したパフォーマンス向上を実現できるようにします。

  • プロファイルとバイナリの分析: 新しいプロファイルの内容(ホット関数、サンプル数、プロファイル サイズなど)を以前のバージョンと厳密に比較します。また、プロファイルを使用して新しいカーネル イメージをビルドし、バイナリを分析して、テキスト セクションの変更が想定どおりであることを確認します。
  • パフォーマンスの検証: 新しいカーネル イメージでターゲット ベンチマークを実行します。これにより、以前のベースラインで確立されたパフォーマンスの改善が維持されることを確認します。

継続的な更新

コードは時間の経過とともに自然に「ドリフト」するため、静的プロファイルは最終的に効果を失います。最高のパフォーマンスを維持するために、パイプラインを継続的に実行して定期的な更新を行います。

  • 定期的な更新: 各 GKI リリースの前に、Android カーネル LTS ブランチのプロファイルを更新し、すべてのビルドに最新のプロファイル データが含まれるようにします。
  • 今後の拡張: 現在、これらの更新は android16-6.12 ブランチと android15-6.6 ブランチに配信されており、今後の android17-6.18 などの新しい GKI バージョンへのサポートを拡大する予定です。

安定性の確保

プロファイル ガイド付き最適化に関する一般的な疑問は、安定性のリスクが生じるかどうかです。AutoFDO は、ソースコードのロジックを変更するのではなく、主にコンパイラのヒューリスティック(関数のインライン化やコード レイアウトなど)に影響するため、カーネルの機能的な整合性を維持します。この技術はすでに大規模に実証されており、Android プラットフォーム ライブラリ、ChromeOS、Google 独自のサーバー インフラストラクチャの標準的な最適化として長年使用されています。

動作の一貫性をさらに保証するために、「デフォルトで保守的」な戦略を適用しています。忠実度の高いプロファイルでキャプチャされていない関数は、標準のコンパイラ メソッドを使用して最適化されます。これにより、カーネルの「コールド」部分や実行頻度の低い部分が標準ビルドと同じように動作し、パフォーマンスの低下やエッジケースでの予期しない動作を防ぐことができます。

今後

現在、android16-6.12 ブランチと android15-6.6 ブランチに AutoFDO をデプロイしています。この最初のロールアウトに加えて、この技術をさらに強化するための有望な方法がいくつかあります。

  • リーチの拡大: 現在の aarch64 サポートに加えて、新しい GKI カーネル バージョンと追加のビルドターゲットに AutoFDO プロファイルをデプロイすることを楽しみにしています。
  • GKI モジュールの最適化: 現在、最適化はメインのカーネル バイナリ(vmlinux)に重点を置いています。AutoFDO を GKI モジュールに拡張することで、カーネル サブシステムのより大きな部分でパフォーマンスのメリットを得ることができます。
  • ベンダー モジュールのサポート: ドライバ開発キット(DDK)を使用してビルドされたベンダー モジュールに対する AutoFDO のサポートにも関心があります。ビルドシステム(Kleaf)とプロファイリング ツール(simpleperf)でサポートがすでに提供されているため、ベンダーはこれらの最適化手法を特定のハードウェア ドライバに適用できます。
  • プロファイル カバレッジの拡大: より広範なクリティカル ユーザー ジャーニー(CUJ)からプロファイルを収集して最適化できる可能性があります。

AutoFDO を Android カーネルに導入することで、OS の基盤が、デバイスを毎日使用する方法に合わせて最適化されるようにしています。

執筆者:

続きを読む