このガイドでは、Android Dynamic Performance Framework(ADPF)を使用して、Android の動的な温度、CPU、GPU の管理機能に基づきゲームを最適化する方法について説明します。対象はゲームですが、この機能は高いパフォーマンスを必要とする他のアプリにも使用できます。
ADPF は、ゲームや高いパフォーマンスを必要とするアプリが Android デバイスの電力システムや温度システムをより直接的に操作できるようにする API のセットです。これらの API を使用することで、Android システムでの動的な動作をモニタリングし、デバイスを過熱状態にしない持続可能なレベルでゲームのパフォーマンスを最適化することができます。
モバイル SoC や Android のパフォーマンス動作は、デスクトップやコンソールより動的です。これらの動作には、温度状態の管理、CPU クロックや GPU クロックの変更、CPU コアの種類の変更などが含まれます。SoC のますます多様化するコアトポロジとの組み合わせにより、デバイスのパフォーマンスに悪影響を与えることなくゲームがこの動作を確実に利用できるようにすることは簡単ではありません。ADPF は、パフォーマンスの予測可能性を高めるためにこの情報の一部を提供します。
ADPF の主な機能は次のとおりです。
温度状態のモニタリング: デバイスの温度状態をモニタリングし、持続できなくなる前にパフォーマンスを事前に調整します。
CPU パフォーマンスのヒント: パフォーマンスのヒントを提供することで、Android が以前のワークロードに基づいて選択するのではなく、適切な CPU クロックとコアの種類を選択できるようにします。
固定パフォーマンス モード: ベンチマークの際にデバイスで固定パフォーマンス モードを有効にし、動的な CPU クロック設定によって変動することのない測定値を取得します。
温度状態のモニタリング
リリース済み: Android 11(API レベル 30)
すべてのデバイスで必須: Android 13(API レベル 33)以上
アプリの潜在的なパフォーマンスは、デバイスの温度状態によって制限され、天気、最近の使用状況、デバイスの温度設計などの特性に応じて変化する可能性があります。デバイスが高いレベルのパフォーマンスを維持できるのは、サーマル スロットリングが行われる前の一定の期間に限られます。実装の主な目標は、温度の上限を超えることなくパフォーマンス目標を達成することです。さらに、パフォーマンスの問題をデバッグする際は、デバイスの温度状態によってパフォーマンスが制限されるタイミングを把握することが重要です。
通常、ゲームエンジンには、エンジンがデバイスにかけるワークロードを調整できるランタイム パフォーマンス パラメータがあります。たとえば、これらのパラメータで、ワーカー スレッドの数、大きなコアと小さなコアのワーカー スレッド アフィニティ、GPU の忠実度オプション、フレームバッファの解像度を設定できます。
デバイスが安全ではない温度状態に近づくと、ゲームはこれらのパラメータを使用してワークロードを軽減することでスロットリングを回避できます。スロットリングを回避するには、デバイスの温度状態をモニタリングし、ゲームエンジンのワークロードを事前に調整する必要があります。デバイスが過熱状態になったら、放熱のために、ワークロードは持続可能なパフォーマンス レベルを割らざるを得ません。
PowerManager
ADPF には、デバイスの温度状態をモニタリングするための PowerManager
クラスがあります。主な要素は次のとおりです。
デバイスがサーマル スロットリングを受けていない場合:
スロットリングが一部行われるが、パフォーマンスには大きく影響しない:
パフォーマンスに影響する重大なスロットリング:
thermal API のネイティブ バインディング(NDK):
デバイスの温度状態をモニタリングするには、getThermalHeadroom
メソッドをポーリングします。このメソッドは、デバイスが過熱状態になることなく現在のパフォーマンス レベルを維持できる期間を判断します。維持できる期間がワークロードの実行に必要な期間よりも短い場合、ゲームはワークロードを持続可能なレベルまで下げる必要があります。たとえば、ゲームはより小さなコアに移行したり、フレームレートを下げたり、忠実度を下げたりする可能性があります。
CPU パフォーマンスのヒント
リリース済み: Android 12(API レベル 31)
すべてのデバイスで必須: まだ必須ではない
CPU パフォーマンスのヒントを使用すると、デバイスを過熱状態にして無駄な電力を使うことなく、ゲームは動的な CPU パフォーマンス動作に影響を与えることができます。ほとんどのデバイスでは、Android は以前の需要に基づいて、ワークロードの CPU クロック速度とコアの種類を動的に調整します。ワークロードによる CPU リソースの使用量が多くなると、クロック速度が上がり、ワークロードは最終的により大きなコアに移行します。ワークロードによるリソースの使用量が少なくなると、Android はリソースの割り当てを減らします。
クロック速度
Android デバイスが CPU クロック速度を動的に調整する場合は、周波数により、コードのパフォーマンスへの影響が変化することがあります。動的なクロック速度に対応するコード設計は、パフォーマンスの最大化、安全な温度状態の維持、効率的な電力の使用にとって重要です。最高のクロック速度でゲームを実行すると、一時的にジャンクを軽減してレスポンシブを向上させることができますが、電力が消費され、最終的にクロックのサーマル スロットリングを招きます。CPU クロックまたは GPU クロックのスロットリングが行われると、パフォーマンスは持続可能なレベルを下回ります。
アプリのコードで CPU 周波数を直接割り当てることはできません。そのため、アプリは CPU クロック速度を上げて実行しようとすると一般的に、バックグラウンド スレッドでビジーループを実行することになるため、ワークロードがより求められるようになります。これにより、アプリが追加リソースを使用していないときも無駄な電力がかかり、デバイスの熱負荷が高まります。
コアの種類
ゲームを実行する CPU コアの種類も、もう 1 つの重要なパフォーマンス要因です。Android デバイスは、一般に、スレッドに割り当てられた CPU コアを最近のワークロード動作に基づいて動的に変更します。コアの種類が複数ある SoC では、CPU コアの割り当てはさらに複雑になります。これらのデバイスの一部では、大きなコアは短時間しか使用できず、温度的に持続できない状態になることはありません。
ゲームでは、次の理由により CPU コア アフィニティを設定しないようにしてください。
ワークロードに最適なコアの種類は、デバイスのモデルによって異なります。
大きなコアの実行の持続可能性は、SoC によって異なります。また、各デバイスのモデルに用意されている各種の温度ソリューションによっても異なります。
環境が温度状態に与える影響は、コアの選択をさらに複雑にする可能性があります。たとえば、天気やスマートフォン ケースにより、デバイスの温度状態が変わることがあります。
コアの選択は、パフォーマンス機能や温度機能が追加された新しいデバイスには適応しない可能性があります。このため、デバイスは一般に、ゲームのプロセッサ アフィニティを無視します。
PeformanceHintManager
ADPF の PerformanceHintManager
クラスによって、ゲームは CPU クロック速度とコアの種類について Android にパフォーマンスのヒントを与えることができます。OS はデバイスの SoC と温度ソリューションに基づき、そのヒントを最適に使用する方法を判断できます。アプリがこの API と温度状態のモニタリングを使用すれば、スロットリングを招く可能性があるビジーループやその他のコーディング手法を使用する代わりに、OS にさらに多くの情報を含むヒントを提供できます。
ゲームがパフォーマンスのヒントを使用する仕組みは以下のとおりです。
同じように動作する主要スレッドのヒント セッションを作成します。次に例を示します。
- レンダリング スレッドが 1 つのセッションを取得する
- IO スレッドが別のセッションを取得する
- オーディオ スレッドが 3 番目のセッションを取得する
ゲームは、セッションがさらにシステム リソースを必要とする少なくとも 2 ミリ秒前、可能であれば 4 ミリ秒以上前に、早い段階で次の処理を行う必要があります。
ヒント セッションごとに、各セッションの実行に必要な時間を予測します。一般的な時間はフレーム間隔に相当しますが、ワークロードがフレーム間で著しく変動しなければ、アプリはより短い間隔を使用できます。
固定パフォーマンス モード
リリース済み: Android 11(API レベル 30)
すべてのデバイスで必須: まだ必須ではない
Android デバイスは、システムの負荷に応じて動的にクロックを変更できます。この動作は、使用時の電力の節約には適していますが、信頼できるパフォーマンス データを取得しにくくなる可能性があります。回帰を防ぐためにはコード フラグメントをどのくらいの速さで実行すればよいかや、最適化が繰り返し可能かどうかを判断する場合には、固定クロック速度でテストしないと、信頼できる結果を得ることができません。固定クロックを使用すると、要因である CPU 周波数を変更することなく、パフォーマンスの正確な A/B テストを実行できます。
固定パフォーマンス モードは、上限と下限での CPU クロックと GPU クロックを設定します。このモードを使用しても、コアの選択など、その他の動的なパフォーマンス動作が無効になることはありません。
固定パフォーマンス モードを有効にするには、以下の adb コマンドを使用します。
adb shell cmd power set-fixed-performance-mode-enabled [true|false]
このモードはデバイスを温度的に持続可能な状態にするものではないため、固定パフォーマンス モードで実行しているデバイスでも過熱状態になることがあります。このため、ベンチマークを実行する場合は以下のことをおすすめします。
デバイスが温度的に持続可能な状態に戻るまで待ってから、実行を開始します。
テスト中にデバイスの温度状態をモニタリングし、ベンチマーク コードと温度イベントとの影響の違いを確認します。
サンプルアプリ
ADPF のサンプルアプリは、ADPF API の基本的な使用例を示しています。このサンプルアプリは、ADPF の getThermalHeadroom
API と thermal status API を使用して、デバイスの温度ステータスを表示します。また、レンダリング スレッドのパフォーマンスを制御するために、API のヒントと PerformanceHintManager
API に基づいてワークロードを動的に変更します。