Yayınlanma tarihi:
Android 11 (API düzeyi 30) - Termal API
Android 12 (API düzeyi 31) - NDK API
(Önizleme) Android 15 (DP1) - getThermalHeadroomThresholds()
Uygulamanızın potansiyel performansı, cihazın termal durumuyla sınırlıdır. Bu durum hava durumu, son kullanım ve cihazın termal tasarımı gibi özelliklere göre değişiklik gösterebilir. Cihazlar, termal olarak sınırlandırılmadan önce yalnızca sınırlı bir süre boyunca yüksek performans sağlayabilir. Uygulamanızın temel hedeflerinden biri, termal sınırlamaları aşmadan performans hedeflerine ulaşmaktır. Termal API, cihaza özel optimizasyonlara gerek kalmadan bunu mümkün kılar. Ayrıca, performans sorunlarında hata ayıklama yaparken cihazınızın termal durumunun performansı sınırlayıp sınırlamadığını bilmek önemlidir.
Oyun motorlarında genellikle motorun cihaza yüklediği iş yükünü ayarlayabilen çalışma zamanı performans parametreleri bulunur. Örneğin, bu parametreler çalışan iş parçacıklarının sayısını, büyük ve küçük çekirdekler için çalışan iş parçacığı yakınlığını, GPU doğruluk seçeneklerini ve çerçeve önbelleği çözünürlüklerini ayarlayabilir. Unity Engine'de oyun geliştiriciler, Adaptive Performance eklentisini kullanarak Kalite Ayarlarını değiştirerek iş yükünü ayarlayabilir. Unreal Engine için kalite düzeylerini dinamik olarak ayarlamak üzere Ölçeklenebilirlik Ayarları'nı kullanın.
Bir cihaz güvenli olmayan bir termal duruma yaklaştığında, oyununuz bu parametreler aracılığıyla iş yükünü azaltarak tıkanmayı önleyebilir. Yavaşlatmayı önlemek için cihazın termal durumunu izlemeniz ve oyun motoru iş yükünü proaktif olarak ayarlamanız gerekir. Cihaz aşırı ısındığında, ısının dağıtılması için iş yükü sürdürülebilir performans seviyesinin altına düşmelidir. Termal marj daha güvenli seviyelere düştüğünde oyun, kalite ayarlarını tekrar artırabilir. Ancak optimum oyun süresi için sürdürülebilir bir kalite düzeyi bulduğunuzdan emin olun.
getThermalHeadroom
yöntemini sorgulayarak cihazın termal durumunu izleyebilirsiniz. Bu yöntem, cihazın aşırı ısınmadan mevcut performans düzeyini ne kadar süre koruyabileceğini tahmin eder. Zaman, iş yükünü çalıştırmak için gerekenden azsa oyununuz iş yükünü sürdürülebilir bir seviyeye düşürmelidir. Örneğin, oyun daha küçük çekirdeklere geçebilir, kare hızını düşürebilir veya doğruluğu azaltabilir.
![ADPF Termal API Ön Entegrasyonu](https://developer.android.google.cn/static/games/optimize/adpf/images/adpf_thermal_pre-integration.png?authuser=4&hl=tr)
![ADPF Termal API Entegrasyon Sonrası](https://developer.android.google.cn/static/games/optimize/adpf/images/adpf_thermal_post-integration.png?authuser=4&hl=tr)
Termal Yönetici'yi edinme
Termal API'yi kullanmak için önce Termal Yöneticisi'ni edinmeniz gerekir.
C++
AThermalManager* thermal_manager = AThermal_acquireManager();
Java
PowerManager powerManager = (PowerManager)this.getSystemService(Context.POWER_SERVICE);
Daha fazla kontrol için termal marjı x saniye ileriye tahmin edin
Sistemden mevcut iş yükü ile x saniye ilerideki sıcaklığı tahmin etmesini isteyebilirsiniz. Bu sayede, termal sınırlamanın devreye girmesini önlemek için iş yükünü azaltarak daha ayrıntılı bir kontrol sahibi olur ve daha fazla tepki verme süresi elde edersiniz.
Sonuç 0,0f (daraltma yok, THERMAL_STATUS_NONE
) ile 1,0f (ağır daraltma, THERMAL_STATUS_SEVERE
) arasında değişir. Oyunlarınızda farklı grafik kalitesi seviyeleri varsa Isıtma Boşluğu Yönergelerimizi uygulayabilirsiniz.
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);
Alternatif olarak, netlik için termal duruma güvenebilirsiniz
Her cihaz modeli farklı şekilde tasarlanmış olabilir. Bazı cihazlar ısıyı daha iyi dağıtabilir ve bu nedenle, ısı sınırına ulaşmadan daha yüksek termal marja dayanabilir. Isıtma marjı aralıkları için basitleştirilmiş bir gruplandırma okumak istiyorsanız mevcut cihazdaki ısıtma marjı değerini anlamak için ısıtma durumunu kontrol edebilirsiniz.
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);
Termal durum değiştiğinde bildirim alın
Ayrıca, thermalStatus
belirli bir seviyeye (örneğin: THERMAL_STATUS_LIGHT
) ulaşana kadar thermalHeadroom
'ü sorgulamak zorunda kalmazsınız. Bunun için, durum değiştiğinde sistemin sizi bilgilendirmesi için geri çağırma işlevi kaydedebilirsiniz.
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);
İşiniz bittiğinde dinleyiciyi kaldırmayı unutmayın.
C++
int result = AThermal_unregisterThermalStatusListener(thermal_manager, callback);
if ( result != 0 ) {
// failed, check whether the callback has been registered previously
}
Java
powerManager.removeThermalStatusListener(listener);
Temizle
İşlemi tamamladığınızda, edindiğiniz thermal_manager öğesini temizlemeniz gerekir. Java kullanıyorsanız PowerManager referansı sizin için otomatik olarak çöp toplanabilir. Ancak Java API'yi JNI üzerinden kullanıyorsanız ve bir referans tuttuysanız referansı temizlemeyi unutmayın.
C++
AThermal_releaseManager(thermal_manager);
Hem C++ API'yi (NDK API) hem de Java API'yi (JNI aracılığıyla) kullanarak Thermal API'yi yerel bir C++ oyununa uygulamayla ilgili eksiksiz bir kılavuz için Uyumluluk kod laboratuvarının Thermal API'yi entegre etme bölümüne göz atın.
Isıtma payı yönergeleri
getThermalHeadroom
yöntemini sorgulayarak cihazın termal durumunu izleyebilirsiniz. Bu yöntem, cihazın THERMAL_STATUS_SEVERE
değerine ulaşmadan önce mevcut performans düzeyini ne kadar süre boyunca koruyabileceğini tahmin eder.
Örneğin, getThermalHeadroom(30)
0,8 döndürürse bu, 30 saniye içinde boş alanın 0,8'e ulaşmasının beklendiğini gösterir. Bu durumda, şiddetli daralmadan 0,2 uzaklıkta veya 1,0'dasınız demektir. Zaman, iş yükünü çalıştırmak için gerekenden azsa oyununuz iş yükünü sürdürülebilir bir seviyeye düşürmelidir. Örneğin, oyun kare hızını düşürebilir, doğruluğu azaltabilir veya ağ bağlantısı çalışmasını azaltabilir.
Isıtma durumları ve anlamları
- Cihaz termal olarak kısıtlanmıyorsa:
- Performans üzerinde önemli bir etkisi olmasa da biraz azaltma:
- Performansı etkileyen önemli bir throttling:
Thermal API'nin cihaz sınırlamaları
Termal API'nin eski cihazlarda uygulanması nedeniyle, Termal API ile ilgili bilinen bazı sınırlamalar veya ek şartlar vardır. Sınırlılıklar ve bu sınırlamaların nasıl aşıldığı aşağıda açıklanmıştır:
GetThermalHeadroom()
API'yi çok sık çağırmayın. Bunu yaparsanız APINaN
değerini döndürür. 10 saniyede bir defadan fazla arama yapmamalısınız.- Birden fazla iş parçacığında çağrı yapmaktan kaçının. Bu, çağrı sıklığını kontrol etmeyi zorlaştırır ve API'nin
NaN
döndürmesine neden olabilir. GetThermalHeadroom()
değerinin başlangıç değeri NaN ise API cihazda kullanılamazGetThermalHeadroom()
yüksek bir değer döndürüyorsa (ör. 0, 85 veya daha yüksek) veGetCurrentThermalStatus()
hâlâTHERMAL_STATUS_NONE
döndürüyorsa durum büyük olasılıkla güncellenmemiştir. Doğru termal kısıtlama durumunu tahmin etmek için sezgisel yöntemler kullanın veyagetCurrentThermalStatus()
olmadan yalnızcagetThermalHeadroom()
kullanın.
Buluşsal yöntemler örneği:
- Termal API'nin desteklenip desteklenmediğini kontrol edin.
isAPISupported()
,getThermalHeadroom
'a yapılan ilk çağrının değerinin 0 veya NaN olmadığından emin olmak için değerini kontrol eder ve ilk değer 0 veya NaN ise API'yi kullanmayı atlar. getCurrentThermalStatus()
,THERMAL_STATUS_NONE
dışında bir değer döndürüyorsa cihaz termal olarak kısıtlanıyordur.getCurrentThermalStatus()
sürekli olarakTHERMAL_STATUS_NONE
döndürüyorsa bu, cihazın termal olarak kısıtlanmadığı anlamına gelmez. Bu,getCurrentThermalStatus()
'ün cihazda desteklenmediği anlamına gelebilir. Cihazın durumunu kontrol etmek içingetThermalHeadroom()
değerinin döndürülen değerini kontrol edin.getThermalHeadroom()
, 1, 0'dan büyük bir değer döndürüyorsa durum aslındaTHERMAL_STATUS_SEVERE
veya daha yüksek olabilir. İş yükünü hemen azaltın vegetThermalHeadroom()
daha düşük bir değer döndürene kadar düşük iş yükünü koruyun.getThermalHeadroom()
0,95 değerini döndürüyorsa durum aslındaTHERMAL_STATUS_MODERATE
veya daha yüksek olabilir. İş yükünü hemen azaltın ve daha yüksek okumaları önlemek için dikkatli olun.getThermalHeadroom()
0,85 değerini döndürüyorsa durum aslındaTHERMAL_STATUS_LIGHT
olabilir.Dikkatli olun ve mümkünse iş yükünü azaltın
Sözde kod:
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.
}
}
}
Diyagram: