रिलीज़ की गई:
Android 11 (एपीआई लेवल 30) - थर्मल एपीआई
Android 12 (एपीआई लेवल 31) - एनडीके एपीआई
(प्रीव्यू) Android 15 (DP1) - getThermalHeadroomThresholds()
डिवाइस के तापमान के हिसाब से, आपके ऐप्लिकेशन की परफ़ॉर्मेंस सीमित हो सकती है. यह तापमान, मौसम, हाल ही में किए गए इस्तेमाल, और डिवाइस के थर्मल डिज़ाइन जैसी विशेषताओं के आधार पर अलग-अलग हो सकता है. डिवाइस, कुछ समय तक ही बेहतर परफ़ॉर्म कर सकते हैं. इसके बाद, ज़्यादा गर्म होने की वजह से उनकी परफ़ॉर्मेंस कम हो जाती है. लागू करने के दौरान आपका मुख्य लक्ष्य, परफ़ॉर्मेंस के लक्ष्यों को हासिल करना होना चाहिए. साथ ही, यह भी ध्यान रखना चाहिए कि डिवाइस का तापमान तय सीमा से ज़्यादा न बढ़े. Thermal API की मदद से, डिवाइस के हिसाब से ऑप्टिमाइज़ेशन करने की ज़रूरत नहीं पड़ती. इसके अलावा, परफ़ॉर्मेंस से जुड़ी समस्याओं को डीबग करते समय, यह जानना ज़रूरी है कि डिवाइस की थर्मल स्थिति की वजह से परफ़ॉर्मेंस सीमित हो रही है या नहीं.
गेम इंजन में आम तौर पर, रनटाइम परफ़ॉर्मेंस पैरामीटर होते हैं. इनकी मदद से, इंजन के डिवाइस पर पड़ने वाले वर्कलोड को अडजस्ट किया जा सकता है. उदाहरण के लिए, इन पैरामीटर की मदद से वर्कर थ्रेड की संख्या, बड़े और छोटे कोर के लिए वर्कर-थ्रेड अफ़िनिटी, जीपीयू फ़िडेलिटी के विकल्प, और फ़्रेमबफ़र रिज़ॉल्यूशन सेट किए जा सकते हैं. Unity Engine में, गेम डेवलपर Adaptive Performance प्लगिन का इस्तेमाल करके, Quality Settings को बदलकर वर्कलोड को अडजस्ट कर सकते हैं. Unreal Engine के लिए, स्केलेबिलिटी सेटिंग का इस्तेमाल करके, क्वालिटी लेवल में डाइनैमिक तरीके से बदलाव करें.
जब कोई डिवाइस ज़्यादा गर्म हो जाता है, तो आपका गेम इन पैरामीटर की मदद से, डिवाइस पर काम का बोझ कम करके थ्रॉटल होने से बच सकता है. थ्रॉटलिंग से बचने के लिए, आपको डिवाइस की थर्मल स्थिति पर नज़र रखनी चाहिए. साथ ही, गेम इंजन के वर्कलोड को पहले से ही अडजस्ट कर लेना चाहिए.
डिवाइस के ज़्यादा गर्म होने पर, काम का बोझ कम होना चाहिए, ताकि डिवाइस का तापमान कम हो सके. जब डिवाइस का तापमान सुरक्षित लेवल पर आ जाता है, तब गेम की क्वालिटी सेटिंग को फिर से बढ़ाया जा सकता है. हालांकि, यह पक्का करें कि गेम की क्वालिटी का लेवल ऐसा हो जिससे उसे ज़्यादा देर तक खेला जा सके.
getThermalHeadroom तरीके से पोल करके, डिवाइस की थर्मल स्थिति पर नज़र रखी जा सकती है. इस तरीके से यह अनुमान लगाया जाता है कि डिवाइस बिना ज़्यादा गर्म हुए, मौजूदा परफ़ॉर्मेंस लेवल को कितने समय तक बनाए रख सकता है. अगर समय, वर्कलोड को पूरा करने के लिए ज़रूरी समय से कम है, तो आपके गेम को वर्कलोड को कम करके एक ऐसे लेवल पर ले जाना चाहिए जहां उसे पूरा किया जा सके. उदाहरण के लिए, गेम छोटे कोर पर स्विच कर सकता है, फ़्रेम रेट कम कर सकता है या फ़िडेलिटी कम कर सकता है.
Thermal Manager ऐक्सेस करना
Thermal API का इस्तेमाल करने के लिए, आपको पहले Thermal Manager को हासिल करना होगा
C++
AThermalManager* thermal_manager = AThermal_acquireManager();
Java
PowerManager powerManager = (PowerManager)this.getSystemService(Context.POWER_SERVICE);
थर्मल हेडरूम के बारे में क्वेरी करना
सिस्टम से मौजूदा थर्मल हेडरूम के बारे में पूछा जा सकता है. इससे यह पता चलता है कि आपका वर्कलोड, थर्मल थ्रॉटलिंग के कितने करीब है. इस एपीआई की मदद से, मौजूदा वर्कलोड के आधार पर x सेकंड पहले तापमान का अनुमान भी लगाया जा सकता है. इससे आपके ऐप्लिकेशन को जवाब देने के लिए ज़्यादा समय मिल सकता है. हालांकि, यह मौजूदा थर्मल स्टेटस का इस्तेमाल करने की तुलना में कम सटीक होगा.
नतीजा 0.0f (कोई थ्रॉटलिंग नहीं,
THERMAL_STATUS_NONE) से लेकर
से 1.0f (ज़्यादा थ्रॉटलिंग,
THERMAL_STATUS_SEVERE) तक सेट किया जा सकता है.
अगर आपके गेम में ग्राफ़िक क्वालिटी के अलग-अलग लेवल हैं, तो थर्मल हेडरूम से जुड़े दिशा-निर्देशों का पालन करें.
C++
float thermal_headroom = AThermal_getThermalHeadroom(0);
ALOGI("ThermalHeadroom: %f", thermal_headroom);
Java
float thermalHeadroom = powerManager.getThermalHeadroom(0);
Log.d("ADPF", "ThermalHeadroom: " + 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);
डिवाइस के तापमान में बदलाव होने पर सूचना पाना
thermalHeadroom के किसी तय लेवल (उदाहरण के लिए: THERMAL_STATUS_LIGHT) तक पहुंचने से पहले, thermalHeadroom को पोल करने से भी बचा जा सकता है. इसके लिए, एक कॉलबैक रजिस्टर किया जा सकता है, ताकि स्टेटस में बदलाव होने पर सिस्टम आपको सूचना दे सके.thermalStatus
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++ API (NDK API) और Java API (JNI के ज़रिए) दोनों का इस्तेमाल करके, नेटिव C++ गेम में Thermal API लागू करने के बारे में पूरी जानकारी पाने के लिए, अनुकूलन से जुड़े कोडलैब सेक्शन में Thermal API इंटिग्रेट करें सेक्शन देखें.
थर्मल हेडरूम के दिशा-निर्देश
getThermalHeadroom
तरीके को पोल करके, डिवाइस की थर्मल स्थिति पर नज़र रखी जा सकती है. इस तरीके से यह अनुमान लगाया जाता है कि डिवाइस, THERMAL_STATUS_SEVERE तक पहुंचने से पहले, मौजूदा परफ़ॉर्मेंस लेवल को कितने समय तक बनाए रख सकता है.
उदाहरण के लिए, अगर getThermalHeadroom(30) की वैल्यू 0.8 है, तो इसका मतलब है कि 30 सेकंड में हेडरूम 0.8 तक पहुंच जाएगा. इसमें थ्रॉटलिंग की सीमा 0.2 या 1.0 से दूर है. अगर समय, वर्कलोड को चलाने के लिए ज़रूरी समय से कम है, तो आपके गेम को वर्कलोड को एक ऐसे लेवल तक कम करना चाहिए जिस पर वह चल सके. उदाहरण के लिए, गेम फ़्रेम रेट को कम कर सकता है, फ़िडेलिटी को कम कर सकता है या नेटवर्क कनेक्टिविटी को कम कर सकता है.
डिवाइस के गर्म होने की स्थितियां और उनका मतलब
- अगर डिवाइस की परफ़ॉर्मेंस पर तापमान का असर नहीं पड़ रहा है, तो:
- कुछ थ्रॉटलिंग, लेकिन परफ़ॉर्मेंस पर कोई खास असर नहीं पड़ा:
- थ्रॉटलिंग की वजह से परफ़ॉर्मेंस पर काफ़ी असर पड़ रहा है:
Thermal API के लिए डिवाइस से जुड़ी सीमाएं
पुराने डिवाइसों पर Thermal API लागू करने की वजह से, इसकी कुछ सीमाएं हैं या इसके लिए कुछ अतिरिक्त ज़रूरी शर्तें हैं. इनकी सीमाएं और इन्हें इस्तेमाल करने का तरीका यहां दिया गया है:
GetThermalHeadroom()एपीआई को बार-बार कॉल न करें. ऐसा करने पर, एपीआईNaNदिखाता है. इसे हर 10 सेकंड में एक से ज़्यादा बार कॉल नहीं करना चाहिए.- एक से ज़्यादा थ्रेड से कॉल करने से बचें. इससे कॉल करने की फ़्रीक्वेंसी को कंट्रोल करना मुश्किल हो जाता है. साथ ही, एपीआई
NaNदिखा सकता है. - अगर
GetThermalHeadroom()की शुरुआती वैल्यू NaN है, तो इसका मतलब है कि डिवाइस पर एपीआई उपलब्ध नहीं है - अगर
GetThermalHeadroom()से ज़्यादा वैल्यू (जैसे: 0.85 या इससे ज़्यादा) मिलती है औरGetCurrentThermalStatus()से अब भीTHERMAL_STATUS_NONEमिलता है, तो हो सकता है कि स्थिति अपडेट न हुई हो. सही थर्मल थ्रॉटलिंग की स्थिति का अनुमान लगाने के लिए, अनुमानित अनुभवजन्य डेटा का इस्तेमाल करें या सिर्फ़getThermalHeadroom()का इस्तेमाल करें.getCurrentThermalStatus()का इस्तेमाल न करें.
अनुमान से जुड़े नियम का उदाहरण:
- देखें कि Thermal API काम करता हो.
isAPISupported(),getThermalHeadroomको किए गए पहले कॉल की वैल्यू की जांच करता है, ताकि यह पक्का किया जा सके कि यह 0 या NaN नहीं है. अगर पहली वैल्यू 0 या NaN है, तो यह एपीआई का इस्तेमाल नहीं करता. - अगर
getCurrentThermalStatus(),THERMAL_STATUS_NONEके अलावा कोई और वैल्यू दिखाता है, तो इसका मतलब है कि डिवाइस की परफ़ॉर्मेंस को थर्मल थ्रॉटलिंग की वजह से कम किया जा रहा है. - अगर
getCurrentThermalStatus()लगातारTHERMAL_STATUS_NONEदिखाता है, तो इसका मतलब यह नहीं है कि डिवाइस की परफ़ॉर्मेंस कम नहीं हो रही है. इसका मतलब यह हो सकता है किgetCurrentThermalStatus()की सुविधा, डिवाइस पर काम नहीं करती. डिवाइस की स्थिति की जानकारी देने वाले एट्रिब्यूटgetThermalHeadroom()की वैल्यू देखें. - अगर
getThermalHeadroom()की वैल्यू > 1.0 है, तो स्टेटसTHERMAL_STATUS_SEVEREया इससे ज़्यादा हो सकता है. ऐसे में, तुरंत वर्कलोड कम करें और तब तक कम वर्कलोड बनाए रखें, जब तकgetThermalHeadroom()की वैल्यू कम न हो जाए - अगर
getThermalHeadroom()की वैल्यू 0.95 है, तो स्टेटसTHERMAL_STATUS_MODERATEया इससे ज़्यादा हो सकता है. इसलिए, तुरंत काम करना शुरू करें और वॉचआउट को चालू रखें, ताकि वैल्यू ज़्यादा न हो - अगर
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.
}
}
}
डायग्राम: