Thermal API

Dirilis:

Android 11 (Level API 30) - API Thermal

Android 12 (Level API 31) - API NDK

(Pratinjau) Android 15 (DP1) - getThermalHeadroomThresholds()

Potensi performa aplikasi Anda dibatasi oleh status termal perangkat, yang dapat bervariasi berdasarkan karakteristik seperti cuaca, penggunaan terbaru, dan desain termal perangkat. Perangkat hanya dapat mempertahankan performa untuk jangka waktu terbatas sebelum di-throttle secara termal. Sasaran utama penerapan Anda adalah untuk mencapai sasaran performa tanpa melampaui batasan termal. Dengan Thermal API, Anda dapat melakukannya tanpa untuk pengoptimalan khusus perangkat. Selain itu, saat proses debug performa mengetahui apakah status termal perangkat Anda membatasi kinerja sangatlah penting.

Game engine biasanya memiliki parameter performa runtime yang dapat menyesuaikan beban kerja yang diberikan mesin di perangkat. Misalnya, parameter ini dapat menetapkan jumlah thread pekerja, afinitas thread pekerja untuk core besar dan kecil, opsi fidelitas GPU, dan resolusi framebuffer. Di Unity Engine, game developer dapat menyesuaikan beban kerja dengan mengubah Kualitas Setelan menggunakan plugin Adaptive Performance. Untuk Unreal Engine, gunakan Setelan Skalabilitas untuk menyesuaikan tingkat kualitas secara dinamis.

Saat perangkat mendekati status termal yang tidak aman, game Anda dapat menghindari throttling dengan mengurangi beban kerja melalui parameter ini. Untuk menghindari throttling, Anda harus memantau status termal perangkat dan secara proaktif menyesuaikan beban kerja game engine. Setelah perangkat menjadi terlalu panas, beban kerja harus berkurang di bawah level performa berkelanjutan untuk menghilangkan panas. Sesudah headroom termal berkurang ke level yang lebih aman, game dapat meningkatkan setelan kualitas lagi, tetapi pastikan untuk menemukan tingkat kualitas yang berkelanjutan untuk waktu bermain yang optimal.

Anda dapat memantau status termal perangkat dengan memilih metode getThermalHeadroom. Metode ini memprediksi berapa lama perangkat dapat mempertahankan arus tingkat performa tanpa terlalu panas. Jika waktunya kurang dari jumlah yang diperlukan untuk menjalankan beban kerja, game Anda harus mengurangi beban kerja ke level yang berkelanjutan. Misalnya, game dapat beralih ke core yang lebih kecil, mengurangi kecepatan frame, atau menurunkan fidelitas.

Pra-Integrasi API Thermal ADPF
Gambar 1. Headroom Termal tanpa secara aktif memantau getThermalHeadroom
Pasca-Integrasi API Thermal ADPF
Gambar 2. Thermal Headroom dengan pemantauan aktif `getThermalHeadroom`

Dapatkan Pengelola Termal

Untuk menggunakan Thermal API, pertama-tama Anda harus mendapatkan Thermal Manager

C++

AThermalManager* thermal_manager = AThermal_acquireManager();

Java

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

Perkirakan Headroom Termal x detik di depan untuk kontrol yang lebih besar

Anda dapat meminta sistem untuk memperkirakan suhu x detik ke depan dengan workload saat ini. Ini memberi Anda kontrol yang lebih halus dan lebih banyak waktu untuk bereaksi dengan mengurangi beban kerja untuk mencegah throttling termal terjadi.

Rentang hasilnya dari 0.0f (tanpa throttling, THERMAL_STATUS_NONE) hingga 1,0f (throttling berat, THERMAL_STATUS_SEVERE). Jika Anda memiliki tingkat kualitas grafis yang berbeda di game, Anda dapat mengikuti Panduan Headroom Termal.

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

Atau, andalkan status termal untuk klarifikasi

Setiap model perangkat dapat didesain secara berbeda. Beberapa perangkat mungkin dapat mendistribusikan panas dengan lebih baik sehingga dapat menahan headroom termal yang lebih tinggi sebelum dibatasi. Jika Anda ingin membaca pengelompokan yang disederhanakan dari headroom termal, Anda dapat memeriksa status termal untuk memahami nilai headroom termal pada perangkat saat ini.

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

Dapatkan notifikasi saat status termal berubah

Anda juga dapat menghindari polling thermalHeadroom hingga hit thermalStatus tingkat tertentu (misalnya: THERMAL_STATUS_LIGHT). Untuk melakukannya, Anda bisa mendaftarkan callback agar sistem memberi tahu Anda setiap kali telah berubah.

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

Ingatlah untuk menghapus pemroses jika sudah selesai

C++

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

Java

powerManager.removeThermalStatusListener(listener);

Pembersihan

Setelah selesai, Anda harus membersihkan termal_manager yang diperoleh. Jika Anda menggunakan Java, referensi PowerManager dapat secara otomatis menjadi sampah kumpulkan untuk Anda. Namun, jika Anda menggunakan Java API melalui JNI dan memiliki menyimpan referensi, ingatlah untuk membersihkan referensinya.

C++

AThermal_releaseManager(thermal_manager);

Untuk panduan lengkap cara mengimplementasikan Thermal API pada game C++ native menggunakan baik untuk C++ API (NDK API) maupun Java API (melalui JNI), lihat kursus Mengintegrasikan Bagian Thermal API di Codelab adaptasi bagian.

Panduan headroom termal

Anda dapat memantau status termal perangkat dengan memilih metode getThermalHeadroom. Metode ini memprediksi berapa lama perangkat dapat mempertahankan arus tingkat performa sebelum mencapai THERMAL_STATUS_SEVERE. Misalnya, jika getThermalHeadroom(30) menampilkan 0,8, hal ini menunjukkan bahwa dalam 30 detik, headroom diharapkan mencapai 0,8, di mana ada 0,2 jarak akibat throttling yang parah, atau 1,0. Jika waktunya kurang dari jumlah yang dibutuhkan untuk menjalankan beban kerja, maka game Anda harus mengurangi beban kerja menjadi level organisasi. Misalnya, game dapat mengurangi kecepatan frame, fidelitas yang lebih rendah, atau mengurangi aktivitas konektivitas jaringan.

Status termal dan arti

Batasan perangkat Thermal API

Ada beberapa batasan umum atau persyaratan tambahan dari Thermal API, karena hingga implementasi termal API pada perangkat lama. Keterbatasan dan bagaimana untuk mengatasinya adalah sebagai berikut:

  • Jangan terlalu sering memanggil GetThermalHeadroom() API. Melakukan hal itu akan menyebabkan API mengembalikan NaN. Anda dapat memanggilnya paling banyak sekali per detik.
  • Jika nilai awal GetThermalHeadroom() adalah NaN, API tidak yang tersedia di perangkat
  • Jika GetThermalHeadroom() menampilkan nilai yang tinggi (mis: 0,85 atau lebih) dan GetCurrentThermalStatus() masih menampilkan THERMAL_STATUS_NONE, statusnya adalah kemungkinan tidak diperbarui. Menggunakan heuristik untuk memperkirakan throttling termal yang benar status ini atau hanya gunakan getThermalHeadroom() tanpa getCurrentThermalStatus().

Contoh heuristik:

  1. Pastikan Thermal API didukung. isAPISupported() memeriksa nilai panggilan pertama ke getThermalHeadroom untuk memastikan bahwa itu bukan 0 atau NaN dan melewati API jika nilai pertamanya adalah 0 atau NaN.
  2. Jika getCurrentThermalStatus() menampilkan nilai selain THERMAL_STATUS_NONE, perangkat sedang di-throttle secara termal.
  3. Jika getCurrentThermalStatus() terus menampilkan THERMAL_STATUS_NONE, tidak berarti bahwa perangkat tidak di-throttle secara termal. Bisa berarti getCurrentThermalStatus() tidak didukung pada perangkat. Periksa nilai hasil getThermalHeadroom() untuk memastikan kondisi perangkat.
  4. Jika getThermalHeadroom() menampilkan nilai > 1.0, status ini dapat sebenarnya THERMAL_STATUS_SEVERE atau lebih tinggi, segera kurangi beban kerja dan mempertahankan beban kerja yang lebih rendah hingga getThermalHeadroom() menampilkan nilai yang lebih rendah
  5. Jika getThermalHeadroom() menampilkan nilai 0,95, status dapat berupa sebenarnya THERMAL_STATUS_MODERATE atau lebih tinggi, segera kurangi beban kerja dan tetap waspada untuk mencegah pembacaan yang lebih tinggi
  6. Jika getThermalHeadroom() menampilkan nilai 0,85, status dapat sebenarnya THERMAL_STATUS_LIGHT, jaga agar tetap waspada dan kurangi beban kerja jika memungkinkan

{i>Pseudocode<i} (Kode semu):

  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:

Contoh Heuristik ADPF
Gambar 3.Contoh Heuristik untuk menentukan dukungan Thermal API di perangkat lama