Thermal API

Data wydania:

Android 11 (poziom API 30) – Thermal API

Android 12 (poziom API 31) – NDK API

(Wersja testowa) Android 15 (DP1) – getThermalHeadroomThresholds()

Potencjalna wydajność aplikacji jest ograniczona przez temperaturę które mogą się różnić w zależności od czynników takich jak pogoda, niedawne użytkowanie a także jego termotyp. Urządzenia mogą utrzymać tylko wysoki poziom wydajności przez ograniczony czas, a potem ograniczane termicznie. Klucz należy osiągnąć cele związane ze skutecznością. przekroczenie ograniczeń termicznych. Thermal API umożliwia ten proces bez konieczności pod kątem konkretnych urządzeń. Ponadto podczas debugowania wydajności i określenie, czy temperatura urządzenia ogranicza wydajność, są ważne. Ponadto podczas debugowania problemów z wydajnością i określenie, czy temperatura urządzenia ogranicza wydajność, są ważne.

Wyszukiwarki gier zwykle mają parametry wydajności w czasie działania aplikacji, które mogą dostosowywać które silnik wykorzystuje na urządzeniu. Te parametry pozwalają na przykład ustawić liczbę wątków instancji roboczych, koligację wątków roboczych z dużymi i małymi rdzeniami Opcje wierności GPU i rozdzielczości bufora klatek. Gra w Unity Engine programistów mogą dostosować obciążenie, zmieniając Jakość Ustawienia za pomocą wtyczki Adaptive Performance. W przypadku Unreal Engine skorzystaj z ustawień skalowalności, aby dostosować poziomów jakości.

Gdy urządzenie zbliża się do niebezpiecznego stanu temperatury, gra może uniknąć ograniczane przez zmniejszenie obciążenia za pomocą tych parametrów. Aby unikać ograniczania przepustowości, monitoruj temperaturę urządzenia i aktywnie i dostosować zbiór zadań silnika gry. Gdy urządzenie się przegrzeje, zadanie musi obniżyć poziom wydajności do poziomu zrównoważonego, aby rozprowadzać ciepło. Po pole manewru spada do bezpieczniejszego poziomu, gra może zwiększyć ustawień jakości, ale upewnij się, że masz stały poziom jakości, dla optymalnego czasu grania.

Możesz sprawdzać temperaturę urządzenia, odpytując getThermalHeadroom . Ta metoda przewiduje, jak długo urządzenie może utrzymać bieżący i wydajność bez przegrzania. Jeśli czas jest krótszy od kwoty potrzebne do uruchomienia zadania, Twoja gra powinna zmniejszyć je do i zrównoważony rozwój. Na przykład gra może przejść na mniejsze rdzenie, z liczbą klatek i z niższą jakością.

Wstępna integracja ADPF Thermal API
Rysunek 1. rezerwy termiczne bez aktywnego monitorowania getThermalHeadroom
.
Integracja po integracji interfejsu Thermal API ADPF
Rys. 2. Zapas termiczny z aktywnym monitorowaniem obiektu „getThermalHeadroom”

Otrzymaj Thermal Manager

Aby korzystać z interfejsu Thermal API, musisz najpierw pobrać Thermal Manager.

C++

AThermalManager* thermal_manager = AThermal_acquireManager();

Java

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

Prognozowanie pola manewru termalnego na x sekund do przodu, aby mieć większą kontrolę

Możesz poprosić system o prognozowanie temperatury na czas x sekund do przodu, bieżącego zadania. Dzięki temu masz dokładniejszą kontrolę i więcej czasu zmniejszać obciążenie i uniknąć ograniczenia z powodu przegrzania.

Wynik występuje w zakresie od 0,0f (bez ograniczania, THERMAL_STATUS_NONE) do 1,0f (duże ograniczanie, THERMAL_STATUS_SEVERE). Jeśli w grach masz różne poziomy jakości grafiki, zapoznaj się z naszymi Wskazówki dotyczące rezerwy termalnego.

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

W celu wyjaśnienia możesz też polegać na stanie temperatury.

Każdy model urządzenia może być zaprojektowany w inny sposób. Niektóre urządzenia mogą mieć taką możliwość lepiej rozprowadzają ciepło, dzięki czemu są w stanie wytrzymać większą rezerwę cieplną. przed ograniczeniem. Jeśli chcesz odczytać uproszczoną grupę zakresów w temperaturze pokojowej, możesz sprawdzić stan temperatury, aby ustalić wartość rezerwy termicznej na bieżącym urządzeniu.

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

Otrzymuj powiadomienia o zmianie stanu temperatury

Możesz też unikać odpytywania pliku thermalHeadroom do czasu wystąpienia thermalStatus określony poziom (np. THERMAL_STATUS_LIGHT). W tym celu można zarejestrować wywołanie zwrotne, dzięki któremu system będzie powiadamiał Cię za każdym razem, gdy zmienił się stan.

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

Pamiętaj, aby usunąć detektor, gdy skończysz

C++

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

Java

powerManager.removeThermalStatusListener(listener);

Uporządkuj

Gdy to zrobisz, musisz wyczyścić pozyskany termometr. Jeśli używasz Javy, odniesienie do PowerManagera może być automatycznie usuwane dla Ciebie. Jeśli jednak używasz interfejsu Java API za pośrednictwem JNI i masz zachował plik referencyjny, pamiętaj o usunięciu pliku referencyjnego

C++

AThermal_releaseManager(thermal_manager);

Kompletny przewodnik po implementacji interfejsu Thermal API w natywnej grze C++ z użyciem zarówno API C++ (NDK API), jak i Java API (przez JNI), zapoznaj się z informacjami o integracji Sekcja Thermal API w ćwiczeniach z programowania Adaptability .

Wskazówki dotyczące rezerwy termicznej

Możesz sprawdzać temperaturę urządzenia, odpytując getThermalHeadroom . Ta metoda przewiduje, jak długo urządzenie może utrzymać bieżący poziom skuteczności przed osiągnięciem THERMAL_STATUS_SEVERE. Jeśli na przykład getThermalHeadroom(30) zwraca 0,8, oznacza to, że w 30 s, pole manewru powinno się mieścić w przedziale 0,8, czyli odległości w odległości 0,2 s przed silnym ograniczeniem lub 1, 0. Jeśli czas jest krótszy niż czas potrzebny do uruchamianiu zadania, gra powinna ograniczyć to zadanie do zrównoważonego na poziomie 300%. Na przykład gra może zmniejszyć liczbę klatek, jakość grafiki lub i ograniczenie pracy związanej z połączeniem sieciowym.

Stany termiczne i ich znaczenie

Ograniczenia interfejsu Thermal API na urządzeniach

Istnieją pewne znane ograniczenia i dodatkowe wymagania dotyczące Thermal API. do implementacji interfejsu The API na starszych urządzeniach. Ograniczenia i sposób jak można obejść problem.

  • Nie wywołuj interfejsu API GetThermalHeadroom() zbyt często. Jeśli to zrobisz, spowoduje zwrócenie przez interfejs API wartości NaN. Wywołuj je nie częściej niż raz na sekundę.
  • Jeśli początkowa wartość GetThermalHeadroom() to NaN, interfejs API nie jest dostępne na urządzeniu
  • Jeśli GetThermalHeadroom() zwraca wysoką wartość (np. 0,85 lub większą) oraz GetCurrentThermalStatus() nadal zwraca wartość THERMAL_STATUS_NONE, a jej stan to prawdopodobnie nie zostały zaktualizowane. Wykorzystaj dane heurystyczne do oszacowania prawidłowego ograniczania termicznego lub po prostu użyj funkcji getThermalHeadroom() bez getCurrentThermalStatus().

Przykład danych heurystycznych:

  1. Sprawdź, czy interfejs Thermal API jest obsługiwany. isAPISupported() sprawdza wartość pierwszym wywołaniem funkcji getThermalHeadroom, by upewnić się, że nie jest to 0 ani NaN oraz pomija użycie interfejsu API, jeśli pierwszą wartością jest 0 lub NaN.
  2. Jeśli getCurrentThermalStatus() zwraca wartość inną niż THERMAL_STATUS_NONE, urządzenie jest ograniczane termicznie.
  3. Jeśli funkcja getCurrentThermalStatus() nadal zwraca wartość THERMAL_STATUS_NONE, nie musi to oznaczać, że urządzenie nie jest ograniczane termicznie. Może oznacza, że usługa getCurrentThermalStatus() nie jest obsługiwana na urządzeniu. Sprawdź zwracaną wartość getThermalHeadroom(), aby mieć pewność, że warunek urządzenia.
  4. Jeśli getThermalHeadroom() zwraca wartość > 1.0, może być wynosi THERMAL_STATUS_SEVERE lub więcej, natychmiast zmniejsz obciążenie i utrzymuj mniejsze zadanie, dopóki getThermalHeadroom() nie zwróci niższej wartości
  5. Jeśli getThermalHeadroom() zwraca wartość 0,95, stan może musi wynosić THERMAL_STATUS_MODERATE lub więcej, od razu zmniejsz obciążenie i zwróć uwagę, aby zapobiec wyższemu odczytowi
  6. Jeśli getThermalHeadroom() zwraca wartość 0,85, stan może THERMAL_STATUS_LIGHT, uważaj i zmniejsz nakład pracy jeśli to możliwe

Pseudokod:

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

Diagram:

Przykład heurystyki ADPF
Rysunek 3.Przykład zastosowania heurystyki do określania obsługi Thermal API na starszych urządzeniach