Alat Rendering GPU Profil menunjukkan waktu relatif yang diperlukan oleh tiap tahap pipeline rendering untuk merender frame sebelumnya. Pengetahuan ini dapat membantu Anda mengidentifikasi bottleneck dalam pipeline, agar Anda dapat mengetahui apa saja yang perlu dioptimalkan untuk meningkatkan performa rendering aplikasi.
Halaman ini menjelaskan secara singkat proses yang terjadi selama tiap tahap pipeline, dan membahas masalah yang dapat menyebabkan bottleneck di sana. Sebelum membaca halaman ini, Anda harus mengetahui informasi yang dijelaskan di Rendering GPU Profil. Selain itu, untuk memahami cara kerja semua tahapan, akan bermanfaat jika Anda mengetahui cara kerja pipeline rendering.
Representasi visual
Alat Rendering GPU Profil menampilkan tahapan dan waktu relatifnya dalam bentuk grafik: yaitu histogram berkode warna. Gambar 1 menunjukkan contoh tampilan tersebut.
![](https://developer.android.google.cn/static/topic/performance/images/bars.png?authuser=0000&hl=id)
Gambar 1. Grafik Rendering GPU Profil
Tiap segmen dari tiap batang vertikal yang ditampilkan di grafik Rendering GPU Profil mewakili satu tahap pipeline dan ditandai menggunakan warna tertentu di grafik batang. Gambar 2 menunjukkan kunci arti dari tiap warna yang ditampilkan.
![](https://developer.android.google.cn/static/topic/performance/images/s-profiler-legend.png?authuser=0000&hl=id)
Gambar 2. Legenda Grafik Rendering GPU Profil
Setelah memahami arti tiap warna, Anda dapat menargetkan aspek tertentu aplikasi untuk mencoba mengoptimalkan performa renderingnya.
Tahap-tahap dan artinya
Bagian ini menjelaskan proses yang terjadi selama tiap tahap sesuai dengan warna di Gambar 2, serta penyebab bottleneck yang perlu diwaspadai.
Penanganan input
Tahap penanganan input pipeline mengukur durasi waktu yang dihabiskan oleh aplikasi dalam menangani peristiwa input. Metrik ini menunjukkan durasi waktu yang dihabiskan oleh aplikasi dalam mengeksekusi kode yang dipanggil sebagai hasil dari callback peristiwa input.
Saat segmen ini besar
Nilai tinggi di area ini biasanya akibat terlalu banyak pekerjaan, atau pekerjaan yang terlalu kompleks, yang terjadi di dalam callback peristiwa pengendali input. Karena callback ini selalu terjadi di thread utama, solusi untuk masalah ini berfokus pada pengoptimalan pekerjaan secara langsung, atau pengurangan beban pekerjaan ke thread yang berbeda.
Juga perlu diperhatikan bahwa
scroll RecyclerView
dapat muncul di fase ini.
RecyclerView
akan langsung di-scroll saat memproses peristiwa sentuh. Akibatnya,
hal itu dapat meng-inflate atau mengisi tampilan item baru. Karena alasan ini, operasi ini
harus dibuat secepat mungkin. Alat pembuatan profil sepertiTraceview atau
Systrace dapat membantu Anda menginvestigasi lebih lanjut.
Animasi
Fase Animation menunjukkan kepada Anda durasi waktu yang diperlukan untuk mengevaluasi semua
animator yang berjalan di frame tersebut. Animator yang paling umum adalah
ObjectAnimator
,
ViewPropertyAnimator
, dan
Transisi.
Saat segmen ini besar
Nilai tinggi di area ini biasanya akibat pekerjaan yang dieksekusi karena
beberapa perubahan properti animasi. Misalnya, animasi mengayunkan jari,
yang men-scroll ListView
atau
RecyclerView
,
akan menyebabkan inflation dan pengisian tampilan dalam jumlah besar.
Pengukuran/tata letak
Agar dapat menggambar item tampilan di layar, Android mengeksekusi dua operasi spesifik di tata letak dan tampilan dalam hierarki tampilan.
Pertama, sistem mengukur item tampilan. Setiap tampilan dan tata letak memiliki data spesifik yang menjelaskan ukuran objek di layar. Beberapa tampilan dapat memiliki ukuran tertentu, tampilan lainnya memiliki ukuran yang disesuaikan dengan ukuran container tata letak induk.
Kedua, sistem menyusun tata letak item tampilan. Setelah sistem menghitung ukuran tampilan turunan, sistem dapat melanjutkan dengan tata letak, ukuran dan pemosisian tampilan di layar.
Sistem melakukan pengukuran dan tata letak bukan hanya untuk tampilan yang akan digambar, tetapi juga untuk hierarki induk tampilan tersebut, hingga ke tampilan root.
Saat segmen ini besar
Jika aplikasi menghabiskan banyak waktu per frame di area ini, itu biasanya karena banyaknya volume tampilan yang perlu disusun tata letaknya, atau masalah seperti taksasi ganda di bagian yang salah dalam hierarki. Pada kasus mana pun, penanganan performa melibatkan peningkatan performa hierarki tampilan.
Kode yang Anda tambahkan ke
onLayout(boolean, int, int, int, int)
atau
onMeasure(int, int)
juga dapat menyebabkan masalah
performa. Traceview dan
Systrace dapat membantu Anda memeriksa
callstack untuk mengidentifikasi masalah yang dapat dialami oleh kode.
Gambar
Tahap gambar menerjemahkan operasi rendering tampilan, seperti menggambar latar belakang atau menggambar teks, ke dalam urutan perintah menggambar native. Sistem mencatat perintah tersebut dalam daftar tampilan.
Batang Gambar merekam durasi waktu yang diperlukan untuk menyelesaikan pencatatan perintah
dalam daftar tampilan, untuk semua tampilan yang perlu diupdate di layar
pada frame ini. Waktu yang diukur berlaku untuk kode yang telah Anda tambahkan ke objek
UI di aplikasi. Contoh kode tersebut dapat berupa
onDraw()
,
dispatchDraw()
,
dan berbagai draw ()methods
yang termasuk dalam subclass dari
class Drawable
.
Saat segmen ini besar
Dalam bahasa sederhana, Anda dapat memahami metrik ini dengan menampilkan durasi yang diperlukan
untuk menjalankan semua panggilan ke
onDraw()
untuk tiap tampilan yang tidak divalidasi. Pengukuran
ini menyertakan waktu yang dihabiskan dalam mengirimkan perintah gambar ke turunan dan
drawable yang mungkin ada. Untuk alasan ini, jika Anda melihat lonjakan batang ini,
penyebabnya dapat berupa sejumlah tampilan yang tiba-tiba menjadi tidak divalidasi Pembatalan validasi
mengharuskan untuk membuat ulang daftar tampilan. Dengan kata lain,
waktu yang lama mungkin akibat beberapa tampilan kustom yang memiliki beberapa logika
yang sangat kompleks dalam
metode onDraw()
.
Sinkronisasi/upload
Metrik Sinkronisasi & Upload mewakili waktu yang diperlukan untuk mentransfer objek bitmap dari memori CPU ke memori GPU selama frame saat ini.
Sebagai prosesor yang berbeda, CPU dan GPU memiliki area RAM yang didedikasikan untuk pemrosesan. Saat Anda menggambar bitmap di Android, sistem mentransfer bitmap ke memori GPU sebelum GPU dapat merendernya ke layar. Lalu, GPU menyimpan cache bitmap agar sistem tidak perlu mentransfer data lagi, kecuali tekstur dikeluarkan dari cache tekstur GPU.
Catatan: Di perangkat Lollipop, tahap ini berwarna ungu.
Saat segmen ini besar
Semua resource untuk frame harus berada dalam memori GPU agar dapat digunakan untuk menggambar frame. Ini berarti bahwa nilai tinggi metrik ini dapat menunjukkan sejumlah besar muatan resource kecil atau sejumlah kecil resource yang sangat besar. Kasus yang umum terjadi adalah saat aplikasi menampilkan satu bitmap yang mendekati ukuran layar. Kasus lainnya adalah saat aplikasi menampilkan sejumlah besar thumbnail.
Untuk mengecilkan batang ini, Anda dapat menerapkan teknik seperti:
- Memastikan resolusi bitmap tidak lebih besar dari ukuran yang akan ditampilkan. Misalnya, aplikasi harus menghindari menampilkan gambar 1024x1024 sebagai gambar 48x48.
-
Memanfaatkan
prepareToDraw()
untuk mengupload bitmap terlebih dahulu secara asinkron sebelum fase sinkronisasi berikutnya.
Menerbitkan perintah
Segmen Menerbitkan Perintah mewakili waktu yang diperlukan untuk menerbitkan semua perintah yang diperlukan untuk menggambar daftar tampilan ke layar.
Agar sistem dapat menggambar daftar tampilan ke layar, sistem mengirimkan perintah yang diperlukan ke GPU. Biasanya, sistem melakukan tindakan ini melalui OpenGL ES API.
Proses ini memerlukan waktu karena sistem melakukan transformasi akhir dan penyesuaian nilai untuk tiap perintah sebelum mengirimkan perintah ke GPU. Overhead tambahan kemudian muncul di sisi GPU, yang menghitung perintah akhir. Perintah ini mencakup transformasi akhir, dan penyesuaian nilai tambahan.
Saat segmen ini besar
Waktu yang dihabiskan dalam tahap ini adalah ukuran langsung dari kompleksitas dan kuantitas daftar tampilan yang dirender oleh sistem pada frame tertentu. Misalnya, banyaknya operasi gambar, terutama dalam kasus adanya biaya inheren kecil untuk tiap primitive gambar, dapat meng-inflate waktu ini. Contoh:
Kotlin
for (i in 0 until 1000) { canvas.drawPoint() }
Java
for (int i = 0; i < 1000; i++) { canvas.drawPoint() }
jauh lebih mahal untuk diterbitkan daripada:
Kotlin
canvas.drawPoints(thousandPointArray)
Java
canvas.drawPoints(thousandPointArray);
Tidak selalu ada korelasi 1:1 antara menerbitkan perintah dan menggambar daftar tampilan dengan sebenarnya. Tidak seperti Menerbitkan Perintah, yang mencatat waktu yang diperlukan untuk mengirimkan perintah menggambar ke GPU, metrik Gambar mewakili waktu yang diperlukan untuk mencatat perintah yang diterbitkan ke daftar tampilan.
Perbedaan ini muncul karena daftar tampilan disimpan dalam cache oleh sistem setiap kali memungkinkan. Akibatnya, ada situasi saat scroll, transformasi, atau animasi mengharuskan sistem untuk mengirim ulang daftar tampilan, tetapi tidak harus mem-buildnya ulang dengan sebenarnya—mencatat ulang perintah menggambar—dari awal. Akibatnya, Anda dapat melihat batang "Issue commands” yang tinggi tanpa melihat batang Draw commands yang tinggi.
Buffering proses/pertukaran
Setelah Android selesai mengirimkan semua daftar tampilannya ke GPU, sistem menerbitkan satu perintah akhir untuk memberi tahu driver grafis bahwa sistem sudah selesai dengan frame saat ini. Di titik ini, driver akhirnya dapat menyajikan gambar yang diupdate ke layar.
Saat segmen ini besar
Penting untuk memahami bahwa GPU mengeksekusi pekerjaan secara paralel dengan CPU. Sistem Android menerbitkan perintah menggambar ke GPU, lalu berpindah ke tugas berikutnya. GPU membaca perintah menggambar tersebut dari antrean dan memprosesnya.
Ketika CPU menerbitkan perintah lebih cepat daripada GPU mengonsumsinya, antrean komunikasi antarprosesor dapat menjadi penuh. Jika ini terjadi, CPU akan memblokir dan menunggu hingga ada ruang dalam antrean untuk menempatkan perintah berikutnya. Status antrean penuh ini sering muncul selama tahap Buffering Pertukaran, karena di titik tersebut, perintah dari seluruh frame telah dikirim.
Kunci untuk memitigasi masalah ini adalah mengurangi kompleksitas pekerjaan yang terjadi di GPU, dengan cara yang serupa dengan yang Anda lakukan untuk fase “Menerbitkan Perintah”.
Lain-lain
Selain waktu yang diperlukan oleh sistem render untuk melakukan pekerjaannya, ada set pekerjaan tambahan yang terjadi di thread utama dan tidak berkaitan dengan rendering. Waktu yang dihabiskan oleh pekerjaan ini dilaporkan sebagai waktu lain-lain. Waktu lain-lain biasanya mewakili pekerjaan yang mungkin terjadi di thread UI antara dua frame rendering berturut-turut.
Saat segmen ini besar
Jika nilai ini tinggi, ada kemungkinan bahwa aplikasi memiliki callback, intent, atau pekerjaan lain yang harus dilakukan di thread lain. Alat seperti Pelacakan metode atau Systrace dapat memberikan visibilitas ke dalam tugas yang sedang berjalan di thread utama. Informasi ini dapat membantu Anda menargetkan peningkatan performa.