Thermal API

Veröffentlicht:

Android 11 (API-Level 30) – Thermal API

Android 12 (API-Level 31) – NDK API

(Vorabversion) Android 15 (DP1) – getThermalHeadroomThresholds()

Die potenzielle Leistung deiner App wird durch den Temperaturzustand des Geräts begrenzt. die sich nach dem Wetter, der letzten Nutzung, und das thermische Design des Geräts. Geräte können nur ein hohes für eine begrenzte Zeit, bevor sie thermisch gedrosselt werden. Ein Schlüssel sollte das Erreichen von Leistungszielen ohne die thermischen Beschränkungen überschreiten. Thermal API ermöglicht dies ohne den für gerätespezifische Optimierungen. Außerdem können Sie bei der Fehlerbehebung Wenn der Überhitzungszustand des Geräts die Leistung beeinträchtigt, wichtig.

Spiel-Engines haben meist Parameter für die Laufzeitleistung, Arbeitslast, die die Engine auf dem Gerät platziert. Diese Parameter können beispielsweise die Anzahl der Worker-Threads, die Worker-Thread-Affinität für große und kleine Kerne, Optionen für GPU-Fidelity und Framebuffer-Auflösungen In der Unity Engine Entwickler können die Arbeitslast anpassen, indem sie die Qualität Einstellungen mit dem Plug-in für Adaptive Performance. Für Unreal Engine nutzen Sie die Skalierbarkeitseinstellungen, Qualitätsstufen dynamisch ausführen.

Wenn sich ein Gerät einem unsicheren Temperaturzustand nähert, kann Ihr Spiel verhindern, dass es durch Reduzierung der Arbeitslast durch diese Parameter gedrosselt. Um dies zu vermeiden Drosselung schließen, sollten Sie den Überhitzungszustand des Geräts überwachen die Arbeitslast der Spiel-Engine anzupassen. Sobald das Gerät überhitzt, muss die Arbeitslast die dauerhafte Leistung unterschreiten, um die Wärme abzuleiten. Nachher sich der Thermo-Toleranzbereich auf sicherere Level verringert, kann das Spiel die Qualitätseinstellungen erneut aktivieren, aber achten Sie darauf, eine nachhaltige für eine optimale Spielzeit.

Sie können den Temperaturstatus des Geräts überwachen, indem Sie die getThermalHeadroom . Diese Methode sagt vorher, wie lange das Gerät den aktuellen ohne Überhitzung zu vermeiden. Wenn die Zeit kürzer ist als der Betrag die zum Ausführen der Arbeitslast benötigt werden, um ein nachhaltiges Niveau zu erreichen. So kann das Spiel beispielsweise zu kleineren Kernen wechseln, Frame-Rate oder eine niedrigere Wiedergabequalität.

<ph type="x-smartling-placeholder">
</ph> ADPF Thermal API – Vorintegration
Abbildung 1: Wärmekopfraum ohne aktives Monitoring von getThermalHeadroom
<ph type="x-smartling-placeholder">
</ph> ADPF Thermal API nach der Integration
Abbildung 2. Wärmetoleranz mit aktiver Überwachung von „getThermalHeadroom“

Wärmemanager abrufen

Wenn du die Thermal API verwenden möchtest, musst du zuerst den Thermal Manager beziehen

C++

AThermalManager* thermal_manager = AThermal_acquireManager();

Java

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

Prognostizieren Sie den thermischen Toleranzraum x Sekunden im Voraus, um mehr Kontrolle zu haben

Sie können das System bitten, die Temperatur x Sekunden im Voraus mit dem aktuelle Arbeitsbelastung. Dadurch erhalten Sie eine genauere Kontrolle und haben mehr Zeit, Reduzieren Sie die Arbeitslast, um zu verhindern, dass die Drosselung der Temperatur einsetzt.

Das Ergebnis reicht von 0.0f (keine Drosselung, THERMAL_STATUS_NONE) bis 1.0f (starke Drosselung, THERMAL_STATUS_SEVERE). Wenn du bei deinen Spielen unterschiedliche Grafikqualitätsstufen hast, folge unserer Richtlinien für thermische Toleranz.

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);

Alternativ können Sie zur Klärung den Temperaturstatus heranziehen.

Jedes Gerätemodell kann anders gestaltet sein. Einige Geräte können die Wärme besser verteilen und somit einem höheren Toleranzbereich standhalten können. bevor gedrosselt wird. Wenn Sie eine vereinfachte Gruppierung von Toleranzbereich für die Temperaturspanne ist, können Sie den Temperaturstatus überprüfen, Toleranzbereich für die Temperatur auf dem aktuellen Gerät.

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);

Benachrichtigung erhalten, wenn sich der Temperaturstatus ändert

Sie können auch die Abfrage des thermalHeadroom-Werts vermeiden, bis die thermalStatus-Treffer erreicht sind. auf einer bestimmten Ebene erreicht (z. B. THERMAL_STATUS_LIGHT). Registrieren Sie dazu einen Callback, damit Sie vom System benachrichtigt werden, sobald der hat sich der Status geändert.

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);

Vergessen Sie nicht, den Listener anschließend zu entfernen.

C++

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

Java

powerManager.removeThermalStatusListener(listener);

Bereinigung

Wenn Sie fertig sind, müssen Sie den Wärmemanager bereinigen, den Sie erworben haben. Wenn Sie Java verwenden, kann die PowerManager-Referenz automatisch als Garbage gewertet werden. die für Sie gesammelt wurden. Wenn Sie jedoch die Java API über JNI nutzen und eine Referenz behalten, denke daran, die Referenz zu bereinigen!

C++

AThermal_releaseManager(thermal_manager);

Eine vollständige Anleitung zur Implementierung der Thermal API in einem nativen C++-Spiel mithilfe von sowohl für die C++ API (NDK API) als auch für die Java API (über JNI) verwenden, lesen Sie den Abschnitt Integration Abschnitt „Therem API“ im Codelab zur Anpassungsfähigkeit .

Richtlinien für den Toleranzbereich

Sie können den Temperaturstatus des Geräts überwachen, indem Sie die getThermalHeadroom . Diese Methode sagt vorher, wie lange das Gerät den aktuellen bevor Sie THERMAL_STATUS_SEVERE erreichen. Wenn getThermalHeadroom(30) beispielsweise 0,8 zurückgibt, bedeutet dies, dass in 30 Sekunden ist der Toleranzbereich voraussichtlich 0,8, bei einer Entfernung von 0,2 starker Drosselung oder 1.0. Wenn die Zeit kürzer ist als der für die die Arbeitslast ausführen, sollte Ihr Spiel die Arbeitslast auf eine nachhaltige So kann das Spiel die Framerate, die Grafikqualität oder die Netzwerkkonnektivität reduzieren.

Status und Bedeutung von Temperaturwerten

Geräteeinschränkungen der Thermal API

Es gibt einige bekannte Einschränkungen oder zusätzliche Anforderungen für die Thermal API. Implementierungen der Thermal API auf älteren Geräten. Die Einschränkungen und zur Umgehung dieser Probleme:

  • Rufen Sie die GetThermalHeadroom() API nicht zu oft auf. Dadurch wird dazu führt, dass die API NaN zurückgibt. Sie sollten es höchstens einmal pro Sekunde aufrufen.
  • Wenn der Anfangswert von GetThermalHeadroom() NaN ist, wird die API nicht auf dem Gerät verfügbar
  • GetThermalHeadroom() gibt einen hohen Wert zurück (z.B.0,85 oder mehr) und GetCurrentThermalStatus() gibt immer noch THERMAL_STATUS_NONE zurück, der Status ist werden wahrscheinlich nicht aktualisiert. Anhand von Heuristiken die korrekte Temperaturdrosselung schätzen oder getThermalHeadroom() ohne getCurrentThermalStatus() verwenden.

Beispiel für Heuristik:

  1. Prüfen Sie, ob die Thermal API unterstützt wird. isAPISupported() prüft den Wert von den ersten Aufruf von getThermalHeadroom an, um sicherzustellen, dass er nicht 0 oder NaN ist, und überspringt die Verwendung der API, wenn der erste Wert entweder 0 oder NaN ist.
  2. Wenn getCurrentThermalStatus() einen anderen Wert zurückgibt als THERMAL_STATUS_NONE, das Gerät wird thermisch gedrosselt.
  3. Wenn getCurrentThermalStatus() immer wieder THERMAL_STATUS_NONE zurückgibt, bedeutet aber nicht, dass das Gerät nicht thermisch gedrosselt wird. Es könnte bedeutet, dass getCurrentThermalStatus() auf dem Gerät nicht unterstützt wird. Prüfen Sie den Rückgabewert von getThermalHeadroom(), um den Zustand von auf dem Gerät.
  4. getThermalHeadroom() gibt den Wert > zurück 1.0 ist, könnte der Status tatsächlich THERMAL_STATUS_SEVERE oder höher sein, reduzieren Sie die Arbeitslast sofort und Arbeitslast senken, bis getThermalHeadroom() einen niedrigeren Wert zurückgibt
  5. Wenn getThermalHeadroom() einen Wert von 0,95 zurückgibt, könnte der Status tatsächlich THERMAL_STATUS_MODERATE oder höher, Arbeitslast sofort reduzieren und achten Sie besonders darauf,
  6. Wenn getThermalHeadroom() einen Wert von 0,85 zurückgibt, könnte der Status tatsächlich THERMAL_STATUS_LIGHT sein, achten Sie darauf und reduzieren Sie die Arbeitslast wenn möglich

Pseudocode:

  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.
      }
    }
  }

Diagramm:

<ph type="x-smartling-placeholder">
</ph> Beispiel für eine ADPF-Heuristik
Abbildung 3: Beispiel für eine Heuristik zur Bestimmung der Thermal API-Unterstützung auf älteren Geräten