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) menjatuhkan bingkai atau secara konsisten merender pada 60FPS? Apakah audio diputar tanpa artefak atau muncul? Berapa lama jeda antara pengguna menyentuh layar dan efek yang ditampilkan di layar?
  • Lamanya waktu yang dibutuhkan untuk operasi yang lebih lama (seperti membuka aplikasi).

Yang pertama lebih terlihat daripada yang kedua. Pengguna biasanya melihat jank tetapi mereka tidak akan dapat mengetahui waktu startup aplikasi 500ms vs 600ms kecuali mereka melihat dua perangkat secara berdampingan. Latensi sentuh segera terlihat dan secara signifikan berkontribusi pada persepsi perangkat.

Akibatnya, dalam perangkat yang cepat, pipeline UI adalah hal terpenting dalam sistem selain yang diperlukan untuk menjaga agar pipeline UI tetap berfungsi. Ini berarti bahwa 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 semuanya harus ditunda jika pekerjaan UI dapat dijalankan. Dapat diterima untuk menukar kinerja operasi yang lebih lama (runtime HDR+, startup aplikasi, dll.) untuk mempertahankan UI yang lancar.

Kapasitas vs jitter

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

Kapasitas

Kapasitas adalah jumlah total dari beberapa sumber daya yang dimiliki perangkat selama beberapa waktu. Ini bisa 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 mengabstraksikan komponen individual dan mengasumsikan metrik tunggal yang menentukan kinerja (terutama saat menyetel perangkat baru karena beban kerja yang dijalankan pada perangkat tersebut kemungkinan besar sudah diperbaiki).

Kapasitas sistem bervariasi berdasarkan sumber daya komputasi online. Mengubah frekuensi CPU/GPU adalah cara utama untuk mengubah kapasitas, tetapi ada cara lain seperti mengubah jumlah inti CPU secara online. Dengan demikian, kapasitas sistem sesuai dengan konsumsi daya; mengubah kapasitas selalu menghasilkan perubahan serupa dalam konsumsi daya.

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 sarana untuk melakukannya terbatas pada peningkatan waktu proses (kerangka kerja Android, ART, Bionic, kompiler/driver GPU, kernel).

Naik opelet

Sementara kapasitas yang diperlukan untuk beban kerja mudah dilihat, jitter adalah konsep yang lebih samar. Untuk pengenalan yang baik tentang jitter sebagai penghalang untuk sistem yang cepat, lihat KASUS KINERJA SUPERKOMPUTER 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 pengantar yang bagus untuk mengoptimalkan sistem besar.)

Halaman ini menggunakan istilah jitter untuk menggambarkan apa yang disebut oleh kertas ASCI Q sebagai noise . Jitter adalah perilaku sistem acak yang mencegah pekerjaan yang terlihat berjalan. Seringkali pekerjaan yang harus dijalankan, tetapi mungkin tidak memiliki persyaratan waktu yang ketat yang menyebabkannya berjalan pada waktu tertentu. Karena acak, sangat sulit untuk menyangkal keberadaan jitter untuk beban kerja yang diberikan. 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 tracing atau logging) dapat memperkenalkan jitter mereka sendiri.

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

  • Penjadwalan tertunda
  • Penangan interupsi
  • Kode driver berjalan terlalu lama dengan preemption atau interupsi dinonaktifkan
  • Softirq jangka panjang
  • Pertentangan kunci (aplikasi, kerangka kerja, driver kernel, kunci pengikat, kunci mmap)
  • Pertentangan deskriptor file di mana utas prioritas rendah menahan kunci pada file, mencegah utas prioritas tinggi berjalan
  • Menjalankan kode penting UI dalam antrian kerja yang dapat ditunda
  • Transisi idle CPU
  • Masuk
  • Keterlambatan I/O
  • Pembuatan proses yang tidak perlu (misalnya, siaran CONNECTIVITY_CHANGE)
  • Penghancuran cache halaman yang disebabkan oleh memori bebas yang tidak mencukupi

Jumlah waktu yang diperlukan untuk periode jitter tertentu dapat berkurang atau tidak seiring dengan peningkatan kapasitas. Misalnya, jika driver membiarkan interupsi dinonaktifkan saat menunggu pembacaan dari seberang bus i2c, itu akan memakan waktu tetap terlepas dari apakah CPU berada pada 384MHz atau 2GHz. Meningkatkan kapasitas bukanlah solusi yang layak untuk meningkatkan kinerja ketika jitter terlibat. Akibatnya, prosesor yang lebih cepat biasanya tidak akan meningkatkan kinerja dalam situasi terbatas jitter.

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

Konsumsi memori

Konsumsi memori secara tradisional disalahkan untuk kinerja yang buruk. Meskipun konsumsi itu sendiri bukan masalah kinerja, hal itu dapat menyebabkan jitter melalui overhead lowmemorykiller, restart layanan, dan page cache thrashing. Mengurangi konsumsi memori dapat menghindari penyebab langsung dari kinerja yang buruk, tetapi mungkin ada peningkatan lain yang ditargetkan untuk menghindari penyebab tersebut juga (misalnya, menyematkan kerangka kerja untuk mencegahnya keluar saat halaman akan segera dibuka setelahnya).

Menganalisis kinerja perangkat awal

Mulai dari sistem yang berfungsi tetapi berkinerja buruk dan mencoba memperbaiki perilaku sistem dengan melihat kasus individual dari kinerja buruk yang terlihat oleh pengguna bukanlah strategi yang tepat. Karena kinerja yang buruk biasanya tidak mudah direproduksi (yaitu, jitter) atau masalah aplikasi, terlalu banyak variabel dalam sistem lengkap mencegah strategi ini menjadi efektif. Akibatnya, sangat mudah untuk salah mengidentifikasi penyebab dan melakukan perbaikan kecil sementara kehilangan peluang sistemik untuk memperbaiki kinerja di seluruh sistem.

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

  1. Dapatkan sistem boot 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 sched_blocked_reason sched_blocked_reason serta tracepoint lain dalam pipa tampilan yang menunjukkan kapan bingkai dikirimkan ke tampilan.
  3. Ambil jejak panjang dari seluruh saluran UI (dari menerima input melalui IRQ hingga pemindaian akhir) sambil menjalankan beban kerja yang ringan dan konsisten (misalnya, UiBench atau tes bola di TouchLatency) .
  4. Perbaiki penurunan bingkai yang terdeteksi dalam beban kerja yang ringan dan konsisten.
  5. Ulangi langkah 3-4 hingga Anda dapat berlari tanpa bingkai yang dijatuhkan selama 20+ detik setiap kali.
  6. Pindah ke sumber jank lain yang terlihat oleh pengguna.

Hal-hal sederhana lainnya yang dapat Anda lakukan sejak awal dalam memunculkan perangkat meliputi:

  • Pastikan kernel Anda memiliki patch titik jejak sched_blocked_reason . Tracepoint ini diaktifkan dengan kategori pelacakan terjadwal di systrace dan menyediakan fungsi yang bertanggung jawab untuk tidur saat utas tersebut memasuki mode tidur tanpa gangguan. Sangat penting untuk analisis kinerja karena tidur yang tidak pernah terputus adalah indikator jitter yang sangat umum.
  • Pastikan Anda memiliki pelacakan yang memadai untuk GPU dan jalur pipa tampilan. Pada Qualcomm SOC terbaru, tracepoints 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 dalam pelacakan tentang pipa tampilan (MDSS) di bagian mdss_fb0 . Di Qualcomm SOCs, Anda tidak akan melihat informasi tambahan apa pun tentang GPU dalam tampilan systrace standar, tetapi hasilnya ada di trace itu sendiri (untuk detailnya, lihat Memahami systrace ).

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

Menggunakan benchmark sintetis

Benchmark sintetis berguna untuk memastikan fungsionalitas dasar perangkat ada. Namun, memperlakukan tolok ukur sebagai proxy untuk kinerja perangkat yang dirasakan tidak berguna.

Berdasarkan pengalaman dengan SOC, perbedaan kinerja benchmark sintetis antara SOC tidak berkorelasi dengan perbedaan serupa dalam kinerja UI yang terlihat (jumlah frame yang dijatuhkan, waktu frame persentil ke-99, dll.). Tolok ukur sintetis adalah tolok ukur khusus kapasitas; jitter berdampak pada kinerja terukur dari tolok ukur ini hanya dengan mencuri waktu dari pengoperasian tolok ukur secara massal. Akibatnya, skor benchmark sintetis sebagian besar 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 mencetak 10.000.
  • SOC 2 merender 99% bingkai dalam 1 md tetapi 1% bingkai dalam 100 md dan skor 19.900, skor yang jauh lebih baik.

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

Menggunakan laporan bug

Laporan bug terkadang berguna untuk analisis kinerja, tetapi karena sangat berat, laporan tersebut jarang berguna untuk men-debug masalah jank sporadis. Mereka mungkin memberikan beberapa petunjuk tentang apa yang dilakukan sistem pada waktu tertentu, terutama jika jank ada di sekitar transisi aplikasi (yang dicatat dalam laporan bug). Laporan bug juga dapat menunjukkan ketika ada sesuatu yang lebih 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 yang lebih disukai 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 persis sesederhana yang terlihat: Bola memantul di sekitar layar selamanya, terlepas dari input pengguna. Biasanya ini juga merupakan tes tersulit untuk berjalan dengan sempurna, tetapi semakin dekat dengan berjalan tanpa bingkai yang jatuh, semakin baik perangkat Anda. Tes bola memantul sulit karena merupakan beban kerja yang sepele tetapi sangat konsisten yang berjalan pada jam yang sangat rendah (ini mengasumsikan perangkat memiliki pengatur frekuensi; jika perangkat malah berjalan dengan jam tetap, turunkan CPU/GPU ke hampir minimum saat menjalankan tes bola memantul untuk pertama kalinya). Saat sistem diam dan jam turun mendekati idle, waktu CPU/GPU yang diperlukan per frame meningkat. Anda dapat menonton bola dan melihat hal-hal jank, dan Anda akan dapat melihat frame yang terlewatkan di systrace juga.

Karena beban kerja sangat konsisten, Anda dapat mengidentifikasi sebagian besar sumber jitter dengan lebih mudah daripada sebagian besar beban kerja yang terlihat oleh pengguna dengan melacak apa yang sebenarnya berjalan pada sistem selama setiap frame yang terlewat, bukan pipeline UI. Jam yang lebih rendah memperkuat efek jitter dengan membuatnya lebih mungkin bahwa setiap jitter menyebabkan frame jatuh. Akibatnya, semakin dekat TouchLatency ke 60FPS, semakin kecil kemungkinan Anda memiliki perilaku sistem yang buruk yang menyebabkan jank sporadis dan sulit direproduksi dalam aplikasi yang lebih besar.

Karena jitter sering (tetapi tidak selalu) clockspeed-invarian, gunakan tes yang berjalan pada jam yang sangat rendah untuk mendiagnosis jitter karena alasan berikut:

  • Tidak semua jitter adalah clockspeed-invarian; banyak sumber hanya menghabiskan waktu CPU.
  • Gubernur harus mendapatkan waktu bingkai rata-rata mendekati tenggat waktu dengan mencatat waktu, sehingga waktu yang dihabiskan untuk menjalankan pekerjaan non-UI dapat mendorongnya melampaui batas untuk menjatuhkan bingkai.