Peningkatan ART Android 8.0

Waktu proses Android (ART) telah ditingkatkan secara signifikan dalam rilis Android 8.0. Daftar di bawah ini merangkum peningkatan yang dapat diharapkan oleh produsen perangkat dalam ART.

Pengumpul sampah pemadatan serentak

Seperti yang diumumkan di Google I/O, ART menampilkan pengumpul sampah (GC) pemadatan serentak baru di Android 8.0. Kolektor ini memadatkan tumpukan setiap kali GC berjalan dan saat aplikasi berjalan, dengan hanya satu jeda singkat untuk memproses akar utas. Ini dia manfaatnya:

  • GC selalu memadatkan heap: rata-rata 32% ukuran heap lebih kecil dibandingkan dengan Android 7.0.
  • Pemadatan memungkinkan alokasi objek penunjuk benjolan lokal utas: Alokasi 70% lebih cepat daripada di Android 7.0.
  • Menawarkan waktu jeda 85% lebih kecil untuk benchmark H2 dibandingkan dengan Android 7.0 GC.
  • Waktu jeda tidak lagi berskala dengan ukuran tumpukan; aplikasi harus dapat menggunakan tumpukan besar tanpa khawatir tentang jank.
  • Detail implementasi GC - Baca hambatan:
    • Hambatan baca adalah sejumlah kecil pekerjaan yang dilakukan untuk setiap bidang objek yang dibaca.
    • Ini dioptimalkan dalam kompiler, tetapi mungkin memperlambat beberapa kasus penggunaan.

Pengoptimalan lingkaran

Berbagai macam optimasi loop digunakan oleh ART dalam rilis Android 8.0:

  • Batas cek eliminasi
    • Statis: rentang terbukti berada dalam batas pada waktu kompilasi
    • Dinamis: tes run-time memastikan loop tetap dalam batas (deopt sebaliknya)
  • Eliminasi variabel induksi
    • Hapus induksi mati
    • Ganti induksi yang digunakan hanya setelah loop dengan ekspresi bentuk tertutup
  • Penghapusan kode mati di dalam loop-body, penghapusan seluruh loop yang menjadi mati
  • Pengurangan kekuatan
  • Transformasi loop: pembalikan, pertukaran, pemisahan, pembukaan gulungan, unimodular, dll.
  • SIMDisasi (juga disebut vektorisasi)

Pengoptimal loop berada di pass pengoptimalannya sendiri di kompiler ART. Kebanyakan optimasi loop mirip dengan optimasi dan penyederhanaan di tempat lain. Tantangan muncul dengan beberapa pengoptimalan yang menulis ulang CFG dengan cara yang lebih rumit dari biasanya, karena sebagian besar utilitas CFG (lihat node.h) fokus pada pembuatan CFG, bukan penulisan ulang.

Analisis hierarki kelas

ART di Android 8.0 menggunakan Analisis Hierarki Kelas (CHA), pengoptimalan kompiler yang mengubah panggilan virtual menjadi panggilan langsung berdasarkan informasi yang dihasilkan dengan menganalisis hierarki kelas. Panggilan virtual mahal karena diimplementasikan di sekitar pencarian vtable, dan membutuhkan beberapa beban dependen. Panggilan virtual juga tidak dapat disejajarkan.

Berikut adalah ringkasan peningkatan terkait:

  • Pembaruan status metode implementasi tunggal dinamis - Pada akhir waktu penautan kelas, ketika tabel telah diisi, ART melakukan perbandingan entri demi entri ke tabel kelas super.
  • Optimalisasi kompiler - Kompiler akan memanfaatkan info implementasi tunggal dari suatu metode. Jika metode A.foo memiliki set flag implementasi tunggal, kompilator akan mendevirtualisasi panggilan virtual menjadi panggilan langsung, dan selanjutnya mencoba untuk menyelaraskan panggilan langsung sebagai hasilnya.
  • Pembatalan kode yang dikompilasi - Juga pada akhir waktu penautan kelas ketika info implementasi tunggal diperbarui, jika metode A.foo yang sebelumnya memiliki implementasi tunggal tetapi status itu sekarang tidak valid, semua kode yang dikompilasi bergantung pada asumsi bahwa metode A. foo memiliki kebutuhan implementasi tunggal agar kode yang dikompilasi tidak valid.
  • Deoptimisasi - Untuk kode kompilasi langsung yang ada di tumpukan, deoptimasi akan dimulai untuk memaksa kode kompilasi yang tidak valid ke mode penerjemah untuk menjamin kebenaran. Mekanisme baru deoptimasi yang merupakan hibrida dari deoptimisasi sinkron dan asinkron akan digunakan.

Cache sebaris dalam file .oat

ART sekarang menggunakan cache inline dan mengoptimalkan situs panggilan yang memiliki cukup data. Fitur cache inline merekam informasi runtime tambahan ke dalam profil dan menggunakannya untuk menambahkan pengoptimalan dinamis ke kompilasi sebelumnya.

Dexlayout

Dexlayout adalah pustaka yang diperkenalkan di Android 8.0 untuk menganalisis file dex dan menyusun ulang menurut profil. Dexlayout bertujuan untuk menggunakan informasi profil runtime untuk menyusun ulang bagian dari file dex selama kompilasi pemeliharaan idle pada perangkat. Dengan mengelompokkan bagian-bagian file dex yang sering diakses bersama-sama, program dapat memiliki pola akses memori yang lebih baik dari lokalitas yang ditingkatkan, menghemat RAM, dan mempersingkat waktu mulai.

Karena informasi profil saat ini hanya tersedia setelah aplikasi dijalankan, dexlayout terintegrasi dalam kompilasi di perangkat dex2oat selama pemeliharaan idle.

Penghapusan cache Dex

Hingga Android 7.0, objek DexCache memiliki empat array besar, sebanding dengan jumlah elemen tertentu dalam DexFile, yaitu:

  • strings (satu referensi per DexFile::StringId),
  • jenis (satu referensi per DexFile::TypeId),
  • metode (satu pointer asli per DexFile::MethodId),
  • bidang (satu penunjuk asli per DexFile::FieldId).

Array ini digunakan untuk pengambilan cepat objek yang sebelumnya kami selesaikan. Di Android 8.0, semua larik telah dihapus kecuali larik metode.

Performa juru bahasa

Performa juru bahasa meningkat secara signifikan dalam rilis Android 7.0 dengan diperkenalkannya "mterp" - juru bahasa yang menampilkan mekanisme pengambilan/dekode/interpretasi inti yang ditulis dalam bahasa rakitan. Mterp dimodelkan setelah interpreter Dalvik cepat, dan mendukung arm, arm64, x86, x86_64, mips dan mips64. Untuk kode komputasi, mterp Art kira-kira sebanding dengan interpreter cepat Dalvik. Namun, dalam beberapa situasi itu bisa secara signifikan - dan bahkan secara dramatis - lebih lambat:

  1. Ajukan kinerja.
  2. Manipulasi string, dan pengguna berat lainnya dari metode yang diakui sebagai intrinsik di Dalvik.
  3. Penggunaan memori tumpukan yang lebih tinggi.

Android 8.0 mengatasi masalah ini.

Lebih sebaris

Sejak Android 6.0, ART dapat menyejajarkan panggilan apa pun dalam file dex yang sama, tetapi hanya dapat menyejajarkan metode daun dari file dex yang berbeda. Ada dua alasan untuk pembatasan ini:

  1. Inlining dari file dex lain perlu menggunakan cache dex dari file dex lain itu, tidak seperti inlining file dex yang sama, yang hanya bisa menggunakan kembali cache dex dari pemanggil. Cache dex diperlukan dalam kode yang dikompilasi untuk beberapa instruksi seperti panggilan statis, beban string, atau beban kelas.
  2. Peta tumpukan hanya mengkodekan indeks metode dalam file dex saat ini.

Untuk mengatasi keterbatasan ini, Android 8.0:

  1. Menghapus akses cache dex dari kode yang dikompilasi (lihat juga bagian "Penghapusan cache Dex")
  2. Memperluas pengkodean peta tumpukan.

Peningkatan sinkronisasi

Tim ART menyetel jalur kode MonitorEnter/MonitorExit, dan mengurangi ketergantungan kami pada penghalang memori tradisional pada ARMv8, menggantinya dengan instruksi yang lebih baru (memperoleh/melepaskan) jika memungkinkan.

Metode asli yang lebih cepat

Panggilan asli yang lebih cepat ke Java Native Interface (JNI) tersedia menggunakan anotasi @FastNative dan @CriticalNative . Pengoptimalan runtime ART bawaan ini mempercepat transisi JNI dan menggantikan notasi !bang JNI yang sekarang sudah tidak digunakan lagi. Anotasi tidak berpengaruh pada metode non-asli dan hanya tersedia untuk kode Bahasa Java platform di bootclasspath (tidak ada pembaruan Play Store).

Anotasi @FastNative mendukung metode non-statis. Gunakan ini jika metode mengakses jobject sebagai parameter atau nilai kembalian.

Anotasi @CriticalNative menyediakan cara yang lebih cepat untuk menjalankan metode asli, dengan batasan berikut:

  • Metode harus statis—tidak ada objek untuk parameter, nilai yang dikembalikan, atau this .
  • Hanya tipe primitif yang diteruskan ke metode asli.
  • Metode asli tidak menggunakan parameter JNIEnv dan jclass dalam definisi fungsinya.
  • Metode harus terdaftar dengan RegisterNatives daripada mengandalkan penautan JNI dinamis.

@FastNative dapat meningkatkan kinerja metode asli hingga 3x, dan @CriticalNative hingga 5x. Misalnya, transisi JNI yang diukur pada perangkat Nexus 6P:

Panggilan Java Native Interface (JNI) Waktu eksekusi (dalam nanodetik)
JNI Reguler 115
!bang JNI 60
@FastNative 35
@CriticalNative 25