Thermal API

リリース日:

Android 11(API レベル 30)- Thermal API

Android 12(API レベル 31)- NDK API

(プレビュー)Android 15(DP1)- getThermalHeadroomThresholds()

アプリの潜在的なパフォーマンスは、デバイスの温度状態によって制限され、天気、最近の使用状況、デバイスの温度設計などの特性に応じて変化する可能性があります。デバイスが維持できるのは 一定の時間パフォーマンスを低下させるため実装の主な目標は、温度の上限を超えることなくパフォーマンス目標を達成することです。Thermal API を使用すると、 デバイス固有の最適化の テストをお試しくださいさらに、パフォーマンスをデバッグする際に デバイスの温度状態によってパフォーマンスが制限されているかどうかを確認する方法は、 重要です

通常、ゲームエンジンには、エンジンがデバイスにかけるワークロードを調整できるランタイム パフォーマンス パラメータがあります。たとえば、これらのパラメータで ワーカー スレッドの数、大小のコアでのワーカーとスレッドのアフィニティ GPU の忠実度オプション、フレームバッファの解像度があります。Unity Engine では、ゲーム デベロッパーは、品質レベルを変更して、 設定 Adaptive Performance プラグインを使用する。 Unreal Engine の場合は、[Scalability Settings] を使用して調整します。 動的に改善できます。

デバイスが安全ではない温度状態に近づくと、ゲームはこれらのパラメータを使用してワークロードを軽減することでスロットリングを回避できます。スロットリングを回避するには、デバイスの温度状態をモニタリングし、ゲームエンジンのワークロードを事前に調整する必要があります。デバイスが過熱すると、ワークロードは 放熱するために持続可能なパフォーマンス レベルを下回った場合。変更後 より安全なレベルまでサーマル ヘッドルームが減少すると、 サステナブルな品質レベルを見つけてください おすすめします。

デバイスの温度状態をモニタリングするには、getThermalHeadroom メソッドをポーリングします。このメソッドは、デバイスが現在の 高いパフォーマンス レベルを維持できます。維持できる期間がワークロードの実行に必要な期間よりも短い場合、ゲームはワークロードを持続可能なレベルまで下げる必要があります。たとえば、ゲームはより小さなコアに移行したり、フレームレートを下げたり、忠実度を下げたりする可能性があります。

<ph type="x-smartling-placeholder">
</ph> ADPF Thermal API の事前統合
図 1.getThermalHeadroom を積極的にモニタリングしない場合のサーマル ヘッドルーム
<ph type="x-smartling-placeholder">
</ph> 統合後の ADPF Thermal API
図 2.「getThermalHeadroom」のアクティブ モニタリングによるサーマル ヘッドルーム

Thermal Manager の取得

Thermal API を使用するには、まず Thermal Manager を取得する必要があります。

C++

AThermalManager* thermal_manager = AThermal_acquireManager();

Java

PowerManager powerManager = (PowerManager)this.getSystemService(Context.POWER_SERVICE);

より細かな制御のために x 秒先にサーマル ヘッドルームを予測します

温度を x 秒先に予測するようシステムに指示できます。 現在のワークロードに応じて異なります。こうすることで、よりきめ細かい管理が可能になり、 ワークロードを減らすことで反応し、サーマル スロットリングが作動しないようにします。

結果の範囲は 0.0f(スロットリングなし、THERMAL_STATUS_NONE)~ 1.0f (大量のスロットリング、THERMAL_STATUS_SEVERE)。 ゲームのグラフィック品質レベルが異なる場合は、 サーマル ヘッドルームのガイドライン

C++

float thermal_headroom = AThermal_getThermalHeadroom(10);
ALOGI("ThermalHeadroom in 10 sec: %f", thermal_headroom);

Java

float thermalHeadroom = powerManager.getThermalHeadroom(10);
Log.d("ADPF", "ThermalHeadroom in 10 sec: " + thermalHeadroom);

または、熱ステータスに基づいて明確にする

デバイスモデルによって設計が異なる場合があります。デバイスによっては、以下のことを実行できる可能性があります。 熱をうまく分散させることで、より高いサーマル ヘッドルームに耐えられる スロットリングされる前にさまざまな範囲を簡単にグループ化して確認したい場合は、 [サーマル ヘッドルーム] では、サーマルのステータスを調べて、 現在のデバイスのサーマル ヘッドルーム値。

C++

AThermalStatus thermal_status = AThermal_getCurrentThermalStatus(thermal_manager);
ALOGI("ThermalStatus is: %d", thermal_status);

Java

int thermalStatus = powerManager.getCurrentThermalStatus();
Log.d("ADPF", "ThermalStatus is: " + thermalStatus);

熱ステータスに変化があったときに通知を受け取る

thermalStatus がヒットするまで thermalHeadroom のポーリングを回避することもできます。 特定のレベル(例: THERMAL_STATUS_LIGHT)。 そのためには、コールバックを登録して、問題が発生したときにシステムから ステータスが変更されました。

C++

int result = AThermal_registerThermalStatusListener(thermal_manager, callback);
if ( result != 0 ) {
  // failed, check whether you have previously registered callback that
  // hasn’t been unregistered
}

Java

// PowerManager.OnThermalStatusChangedListener is an interface, thus you can
// also define a class that implements the methods
PowerManager.OnThermalStatusChangedListener listener = new
  PowerManager.OnThermalStatusChangedListener() {
    @Override
    public void onThermalStatusChanged(int status) {
        Log.d("ADPF", "ThermalStatus changed: " + status);
        // check the status and flip the flag to start/stop pooling when
        // applicable
    }
};
powerManager.addThermalStatusListener(listener);

完了したら、忘れずにリスナーを削除してください。

C++

int result = AThermal_unregisterThermalStatusListener(thermal_manager, callback);
if ( result != 0 ) {
  // failed, check whether the callback has been registered previously
}

Java

powerManager.removeThermalStatusListener(listener);

クリーンアップ

完了したら、取得した thermal_manager をクリーンアップする必要があります。 Java を使用している場合、PowerManager 参照が自動的にガベージとなる可能性がある 自動的に収集されます。ただし、JNI 経由で Java API を使用していて、 忘れずに参照をクリーンアップしてください。

C++

AThermal_releaseManager(thermal_manager);

以下を使用して、ネイティブ C++ ゲームに Thermal API を実装する方法に関する完全なガイドを C++ API(NDK API)と Java API(JNI を使用)のどちらについても、Integrated 適応性 Codelab の Thermal API セクション

サーマル ヘッドルームのガイドライン

デバイスの温度状態をモニタリングするには、getThermalHeadroom メソッドをポーリングします。このメソッドは、デバイスが現在の THERMAL_STATUS_SEVERE に達する前に成果レベルを上げることができます。 たとえば、getThermalHeadroom(30) が 0.8 を返す場合、30 すると、ヘッドルームは 0.8 に達すると予想され、その差は 0.2 秒になります。 スロットリング(1.0)から構成されます。時間が足りない場合や、 サステナブルな範囲までワークロードが減少するはずです。 できます。たとえば、フレームレートを下げたり、忠実度を下げたり、 ネットワーク接続作業を軽減できます。

温度のステータスと意味

Thermal API のデバイスの制限

Thermal API には、いくつかの既知の制限事項または追加要件があります。 Thermal API の実装には使用できません。制限事項と使用方法 回避する方法を以下に紹介します。

  • GetThermalHeadroom() API を頻繁に呼び出さないでください。これにより、 NaN が返されます。1 秒に 1 回まで呼び出す必要があります。
  • GetThermalHeadroom() の初期値が NaN の場合、API は デバイスで利用可能
  • GetThermalHeadroom() が高い値(0.85 以上など)を返し、かつ GetCurrentThermalStatus() が引き続き THERMAL_STATUS_NONE を返す場合、ステータスは 更新されていない可能性があります。ヒューリスティックを使用して適切なサーマル スロットリングを推定する getCurrentThermalStatus() なしで getThermalHeadroom() を使用します。

ヒューリスティックの例:

  1. Thermal API がサポートされていることを確認します。isAPISupported() は次の値を確認します: 0 または NaN ではないことを確認する getThermalHeadroom の最初の呼び出し。 は、最初の値が 0 または NaN の場合、API の使用をスキップします。
  2. getCurrentThermalStatus()THERMAL_STATUS_NONE、デバイスはサーマル スロットリング中です。
  3. getCurrentThermalStatus()THERMAL_STATUS_NONE を返し続ける場合、 必ずしもデバイスがサーマル スロットリングされていないことを意味するわけではありません。かしこまりました。 getCurrentThermalStatus() がデバイスでサポートされていないことを意味します。 getThermalHeadroom() の戻り値を確認して、次の条件が満たされていることを確認します。 クリックします。
  4. getThermalHeadroom() が > の値を返す場合1.0 の場合、ステータスは THERMAL_STATUS_SEVERE 以上であれば、ワークロードをすぐに減らして、 getThermalHeadroom() がより低い値を返すまで低いワークロードを維持する
  5. getThermalHeadroom() が値 0.95 を返した場合、ステータスは次のようになる可能性があります。 実際に THERMAL_STATUS_MODERATE 以上になる場合は、ワークロードをすぐに減らす 読めないことに注意して
  6. getThermalHeadroom() が値 0.85 を返した場合、ステータスは次のようになる可能性があります。 実際には THERMAL_STATUS_LIGHT なので、注意してワークロードを削減してください (可能な場合)

擬似コード:

  bool isAPISupported() {
    float first_value_of_thermal_headroom = getThermalHeadroom();
    if ( first_value_of_thermal_headroom == 0 ||
      first_value_of_thermal_headroom == NaN ) {
        // Checked the thermal Headroom API's initial return value
        // it is NaN or 0,so, return false (not supported)
        return false;
    }
    return true;
  }
  
  if (!isAPISupported()) {
    // Checked the thermal Headroom API's initial return value, it is NaN or 0
    // Don’t use the API
  } else {
      // Use thermalStatus API to check if it returns valid values.
      if (getCurrentThermalStatus() > THERMAL_STATUS_NONE) {
          // The device IS being thermally throttled
      } else {
      // The device is not being thermally throttled currently. However, it
      // could also be an indicator that the ThermalStatus API may not be
      // supported in the device.
      // Currently this API uses predefined threshold values for thermal status
      // mapping. In the future  you may be able to query this directly.
      float thermal_headroom = getThermalHeadroom();
      if ( thermal_headroom > 1.0) {
            // The device COULD be severely throttled.
      } else  if ( thermal_headroom > 0.95) {
            // The device COULD be moderately throttled.
      } else if ( thermal_headroom > 0.85) {
            // The device COULD be experiencing light throttling.
      }
    }
  }

図:

<ph type="x-smartling-placeholder">
</ph> ADPF ヒューリスティックの例
図 3. 古いデバイスで Thermal API のサポートを判断するヒューリスティックの例