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.
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ą.
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
- Jeśli urządzenie nie jest ograniczane termicznie:
- Jest pewne ograniczenie, ale nie wpływa to znacząco na wydajność:
- Znaczne ograniczanie, które wpływa na wydajność:
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ą) orazGetCurrentThermalStatus()
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 funkcjigetThermalHeadroom()
bezgetCurrentThermalStatus()
.
Przykład danych heurystycznych:
- Sprawdź, czy interfejs Thermal API jest obsługiwany.
isAPISupported()
sprawdza wartość pierwszym wywołaniem funkcjigetThermalHeadroom
, 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. - Jeśli
getCurrentThermalStatus()
zwraca wartość inną niżTHERMAL_STATUS_NONE
, urządzenie jest ograniczane termicznie. - 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ługagetCurrentThermalStatus()
nie jest obsługiwana na urządzeniu. Sprawdź zwracaną wartośćgetThermalHeadroom()
, aby mieć pewność, że warunek urządzenia. - Jeśli
getThermalHeadroom()
zwraca wartość > 1.0, może być wynosiTHERMAL_STATUS_SEVERE
lub więcej, natychmiast zmniejsz obciążenie i utrzymuj mniejsze zadanie, dopókigetThermalHeadroom()
nie zwróci niższej wartości - 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 - Jeśli
getThermalHeadroom()
zwraca wartość 0,85, stan możeTHERMAL_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: