Mengevaluasi Kinerja

Gunakan Simpleperf untuk mengevaluasi kinerja perangkat. Simpleperf adalah alat pembuatan profil asli untuk aplikasi dan proses asli di Android. Gunakan CPU Profiler untuk memeriksa penggunaan CPU aplikasi dan aktivitas thread secara real time.

Ada dua indikator kinerja yang terlihat oleh pengguna:

  • Performa yang dapat diprediksi dan terlihat . Apakah antarmuka pengguna (UI) menghapus frame atau secara konsisten merender pada 60FPS? Apakah audio diputar tanpa artefak atau popping? Berapa lama jeda antara pengguna menyentuh layar dan efek muncul di layar?
  • Lamanya waktu yang diperlukan untuk pengoperasian yang lebih lama (seperti membuka aplikasi).

Yang pertama lebih terlihat dibandingkan yang kedua. Pengguna biasanya melihat jank tetapi mereka tidak akan dapat mengetahui waktu startup aplikasi 500 md vs 600 md kecuali mereka melihat dua perangkat secara berdampingan. Latensi sentuhan langsung terlihat dan berkontribusi signifikan terhadap persepsi perangkat.

Akibatnya, dalam perangkat yang cepat, pipeline UI adalah hal terpenting dalam sistem selain yang diperlukan untuk menjaga pipeline UI tetap berfungsi. Artinya, pipeline UI harus mendahului pekerjaan lain yang tidak diperlukan untuk UI yang lancar. Untuk mempertahankan UI yang lancar, sinkronisasi latar belakang, pengiriman notifikasi, dan pekerjaan serupa harus ditunda jika pekerjaan UI dapat dijalankan. Memperdagangkan kinerja operasi yang lebih lama (waktu proses HDR+, startup aplikasi, dll.) dapat diterima untuk mempertahankan UI yang lancar.

Kapasitas vs jitter

Saat mempertimbangkan kinerja perangkat, kapasitas dan jitter adalah dua metrik yang bermakna.

Kapasitas

Kapasitas adalah jumlah total sumber daya yang dimiliki perangkat selama jangka waktu tertentu. Ini dapat berupa sumber daya CPU, sumber daya GPU, sumber daya I/O, sumber daya jaringan, bandwidth memori, atau metrik serupa lainnya. Saat memeriksa kinerja keseluruhan sistem, akan berguna untuk mengabstraksi masing-masing komponen dan mengasumsikan metrik tunggal yang menentukan kinerja (terutama saat menyetel perangkat baru karena beban kerja yang dijalankan pada perangkat tersebut kemungkinan besar sudah tetap).

Kapasitas suatu sistem bervariasi berdasarkan sumber daya komputasi online. Mengubah frekuensi CPU/GPU adalah cara utama untuk mengubah kapasitas, namun ada cara lain seperti mengubah jumlah inti CPU secara online. Oleh karena itu, kapasitas suatu sistem berhubungan dengan konsumsi daya; perubahan kapasitas selalu menghasilkan perubahan konsumsi daya yang serupa.

Kapasitas yang dibutuhkan pada waktu tertentu sangat ditentukan oleh aplikasi yang sedang berjalan. Akibatnya, platform tidak dapat berbuat banyak untuk menyesuaikan kapasitas yang diperlukan untuk beban kerja tertentu, dan cara untuk melakukannya terbatas pada peningkatan runtime (kerangka kerja Android, ART, Bionic, kompiler/driver GPU, kernel).

Naik opelet

Meskipun kapasitas yang diperlukan untuk suatu beban kerja mudah dilihat, jitter adalah konsep yang lebih samar-samar. Untuk pengenalan yang baik tentang jitter sebagai penghambat sistem yang cepat, lihat KASUS KINERJA KOMPUTER SUPER YANG HILANG: MENCAPAI KINERJA OPTIMAL PADA 8.192 PROSESOR ASCl Q . (Ini adalah penyelidikan mengapa superkomputer ASCI Q tidak mencapai kinerja yang diharapkan dan merupakan pengenalan yang bagus untuk mengoptimalkan sistem besar.)

Halaman ini menggunakan istilah jitter untuk menggambarkan apa yang disebut oleh makalah ASCI Q noise . Jitter adalah perilaku sistem acak yang mencegah berjalannya pekerjaan yang terlihat. Seringkali pekerjaan harus dijalankan, namun mungkin tidak memiliki persyaratan waktu yang ketat yang menyebabkannya dijalankan pada waktu tertentu. Karena bersifat acak, sangat sulit untuk menyangkal adanya jitter pada beban kerja tertentu. Juga sangat sulit untuk membuktikan bahwa sumber jitter yang diketahui adalah penyebab masalah kinerja tertentu. Alat yang paling umum digunakan untuk mendiagnosis penyebab jitter (seperti penelusuran atau logging) dapat menyebabkan jitternya sendiri.

Sumber jitter yang dialami dalam implementasi Android di dunia nyata meliputi:

  • Keterlambatan penjadwal
  • Penangan interupsi
  • Kode driver berjalan terlalu lama dengan preemption atau interupsi dinonaktifkan
  • Softirq yang sudah berjalan lama
  • Pertentangan kunci (aplikasi, kerangka kerja, driver kernel, kunci pengikat, kunci mmap)
  • Pertentangan deskriptor file di mana thread berprioritas rendah menahan kunci pada file, mencegah thread berprioritas tinggi berjalan
  • Menjalankan kode penting-UI di antrean kerja yang mungkin tertunda
  • Transisi menganggur CPU
  • Pencatatan
  • penundaan I/O
  • Pembuatan proses yang tidak perlu (misalnya, siaran CONNECTIVITY_CHANGE)
  • Penghancuran cache halaman disebabkan oleh memori bebas yang tidak mencukupi

Jumlah waktu yang diperlukan untuk periode jitter tertentu mungkin berkurang atau tidak seiring bertambahnya kapasitas. Misalnya, jika driver membiarkan interupsi dinonaktifkan saat menunggu pembacaan dari bus i2c, hal ini akan memakan waktu tertentu terlepas dari apakah CPU berada pada 384MHz atau 2GHz. Meningkatkan kapasitas bukanlah solusi yang layak untuk meningkatkan kinerja ketika melibatkan jitter. Akibatnya, prosesor yang lebih cepat biasanya tidak akan meningkatkan kinerja dalam situasi yang dibatasi jitter.

Terakhir, tidak seperti kapasitas, jitter hampir seluruhnya berada dalam domain vendor sistem.

Konsumsi memori

Konsumsi memori secara tradisional dianggap sebagai penyebab kinerja yang buruk. Meskipun konsumsi itu sendiri bukan merupakan masalah kinerja, hal ini dapat menyebabkan jitter melalui overhead yang mematikan memori, restart layanan, dan penghancuran cache halaman. Mengurangi konsumsi memori dapat menghindari penyebab langsung dari kinerja yang buruk, namun mungkin ada perbaikan lain yang ditargetkan untuk menghindari penyebab tersebut juga (misalnya, menyematkan kerangka kerja untuk mencegahnya dikeluarkan ketika akan dimasukkan segera setelahnya).

Menganalisis kinerja perangkat awal

Memulai dari sistem yang berfungsi namun berkinerja buruk dan mencoba memperbaiki perilaku sistem dengan melihat kasus individual dari kinerja buruk yang terlihat oleh pengguna bukanlah strategi yang baik. Karena kinerja yang buruk biasanya tidak mudah direproduksi (misalnya jitter) atau menjadi masalah aplikasi, terlalu banyak variabel dalam sistem penuh menghalangi efektivitas strategi ini. Akibatnya, sangat mudah untuk salah mengidentifikasi penyebab dan melakukan perbaikan kecil, namun kehilangan peluang sistemik untuk memperbaiki kinerja di seluruh sistem.

Sebagai gantinya, gunakan pendekatan umum berikut saat membuka perangkat baru:

  1. Dapatkan sistem melakukan booting ke UI dengan semua driver berjalan dan beberapa pengaturan pengatur frekuensi dasar (jika Anda mengubah pengaturan pengatur frekuensi, ulangi semua langkah di bawah).
  2. Pastikan kernel mendukung tracepoint sched_blocked_reason serta tracepoint lainnya di pipeline tampilan yang menunjukkan kapan frame dikirimkan ke tampilan.
  3. Ambil jejak panjang seluruh pipeline UI (mulai dari penerimaan input melalui IRQ hingga pemindaian akhir) sambil menjalankan beban kerja yang ringan dan konsisten (misalnya, UiBench atau pengujian bola di TouchLatency) .
  4. Memperbaiki penurunan frame yang terdeteksi pada beban kerja yang ringan dan konsisten.
  5. Ulangi langkah 3-4 hingga Anda dapat menjalankan tanpa frame yang hilang selama 20+ detik setiap kalinya.
  6. Beralih ke sumber jank lain yang terlihat oleh pengguna.

Hal sederhana lainnya yang dapat Anda lakukan sejak awal dalam menampilkan perangkat meliputi:

  • Pastikan kernel Anda memiliki patch tracepoint sched_blocked_reason . Titik jejak ini diaktifkan dengan kategori jejak terjadwal di systrace dan menyediakan fungsi yang bertanggung jawab untuk tidur ketika thread tersebut memasuki mode tidur tanpa gangguan. Hal ini penting untuk analisis kinerja karena tidur yang tidak terputus adalah indikator jitter yang sangat umum.
  • Pastikan Anda memiliki penelusuran yang memadai untuk GPU dan saluran tampilan. Pada SOC Qualcomm terbaru, tracepoint diaktifkan menggunakan:
  • adb shell "echo 1 > /d/tracing/events/kgsl/enable"
    adb shell "echo 1 > /d/tracing/events/mdss/enable"
    

    Peristiwa ini tetap diaktifkan saat Anda menjalankan systrace sehingga Anda dapat melihat informasi tambahan di jejak tentang alur tampilan (MDSS) di bagian mdss_fb0 . Pada SOC Qualcomm, Anda tidak akan melihat informasi tambahan apa pun tentang GPU dalam tampilan systrace standar, namun hasilnya ada dalam jejak itu sendiri (untuk detailnya, lihat Memahami systrace ).

    Apa yang Anda inginkan dari penelusuran tampilan semacam ini adalah peristiwa tunggal yang secara langsung menunjukkan bahwa bingkai telah dikirimkan ke layar. Dari sana, Anda dapat menentukan apakah Anda berhasil mencapai waktu frame; jika peristiwa X n terjadi kurang dari 16,7 ms setelah peristiwa X n-1 (dengan asumsi tampilan 60Hz), maka Anda tahu bahwa Anda tidak melakukan jank. Jika SOC Anda tidak memberikan sinyal seperti itu, bekerja samalah dengan vendor Anda untuk mendapatkannya. Men-debug jitter sangat sulit dilakukan tanpa sinyal penyelesaian frame yang pasti.

Menggunakan benchmark sintetis

Tolok ukur sintetis berguna untuk memastikan fungsionalitas dasar perangkat ada. Namun, memperlakukan tolok ukur sebagai proksi kinerja perangkat yang dirasakan tidaklah berguna.

Berdasarkan pengalaman dengan SOC, perbedaan kinerja benchmark sintetis antar SOC tidak berkorelasi dengan perbedaan serupa dalam kinerja UI yang terlihat (jumlah frame yang dihapus, waktu frame persentil ke-99, dll.). Tolok ukur sintetis adalah tolok ukur yang hanya mengandalkan kapasitas; jitter berdampak pada kinerja terukur dari tolok ukur ini hanya dengan mencuri waktu dari sebagian besar pengoperasian tolok ukur tersebut. Akibatnya, sebagian besar skor benchmark sintetis tidak relevan sebagai metrik kinerja yang dirasakan pengguna.

Pertimbangkan dua SOC yang menjalankan Benchmark X yang merender 1000 frame UI dan melaporkan total waktu rendering (skor lebih rendah lebih baik).

  • SOC 1 merender setiap frame Benchmark X dalam 10 md dan mendapat skor 10.000.
  • SOC 2 merender 99% frame dalam 1 md tetapi 1% frame dalam 100 md dan mendapatkan skor 19.900, skor yang jauh lebih baik.

Jika tolok ukur tersebut menunjukkan kinerja UI sebenarnya, SOC 2 tidak akan dapat digunakan. Dengan asumsi kecepatan refresh 60Hz, SOC 2 akan memiliki frame yang tersendat-sendat setiap 1,5 detik pengoperasian. Sementara itu, SOC 1 (SOC yang lebih lambat menurut Benchmark X) akan sangat lancar.

Menggunakan laporan bug

Laporan bug terkadang berguna untuk analisis kinerja, namun karena sangat berat, laporan tersebut jarang berguna untuk men-debug masalah jank yang sporadis. Mereka mungkin memberikan beberapa petunjuk tentang apa yang sedang dilakukan sistem pada waktu tertentu, terutama jika jank terjadi di sekitar transisi aplikasi (yang dicatat dalam laporan bug). Laporan bug juga dapat menunjukkan ketika ada sesuatu yang salah dengan sistem yang dapat mengurangi kapasitas efektifnya (seperti pelambatan termal atau fragmentasi memori).

Menggunakan TouchLatency

Beberapa contoh perilaku buruk berasal dari TouchLatency, yang merupakan beban kerja berkala pilihan yang digunakan untuk Pixel dan Pixel XL. Ini tersedia di frameworks/base/tests/TouchLatency dan memiliki dua mode: latensi sentuh dan bola memantul (untuk beralih mode, klik tombol di sudut kanan atas).

Tes bola memantul sesederhana yang terlihat: Sebuah bola memantul di sekitar layar selamanya, apa pun masukan pengguna. Biasanya ini juga merupakan pengujian yang paling sulit untuk dijalankan dengan sempurna, namun semakin dekat untuk berjalan tanpa frame yang terjatuh, semakin baik perangkat Anda. Pengujian bola pantul sulit dilakukan karena beban kerjanya sepele namun sangat konsisten dan dijalankan pada jam yang sangat rendah (hal ini mengasumsikan perangkat memiliki pengatur frekuensi; jika perangkat berjalan dengan jam tetap, downclock CPU/GPU hingga mendekati minimum saat menjalankan tes bola pantul untuk pertama kalinya). Saat sistem berhenti dan jam semakin mendekati idle, waktu CPU/GPU yang dibutuhkan per frame meningkat. Anda dapat menonton bola dan melihat hal-hal yang tidak terduga, dan Anda juga dapat melihat frame yang terlewat di systrace.

Karena beban kerjanya sangat konsisten, Anda dapat mengidentifikasi sebagian besar sumber jitter dengan lebih mudah dibandingkan sebagian besar beban kerja yang terlihat pengguna dengan melacak apa yang sebenarnya berjalan di sistem selama setiap frame yang terlewat, bukan di pipeline UI. Jam yang lebih rendah memperkuat efek jitter dengan memperbesar kemungkinan jitter menyebabkan frame terjatuh. Akibatnya, semakin dekat TouchLatency ke 60FPS, semakin kecil kemungkinan Anda mengalami perilaku sistem buruk yang menyebabkan jank yang sporadis dan sulit direproduksi pada aplikasi yang lebih besar.

Karena jitter sering kali (tetapi tidak selalu) invarian kecepatan jam, gunakan pengujian yang dijalankan pada jam sangat rendah untuk mendiagnosis jitter karena alasan berikut:

  • Tidak semua jitter bersifat invarian kecepatan jam; banyak sumber hanya menghabiskan waktu CPU.
  • Gubernur harus mendapatkan waktu frame rata-rata mendekati tenggat waktu dengan mengurangi waktu, sehingga waktu yang dihabiskan untuk menjalankan pekerjaan non-UI dapat mendorongnya hingga kehilangan frame.