Android 8.0 ART iyileştirmeleri

Android 8.0 sürümünde Android çalışma zamanı (ART) önemli ölçüde iyileştirildi. Aşağıdaki listede, cihaz üreticilerinin ART'de bekleyebileceği geliştirmeler özetlenmiştir.

Eşzamanlı sıkıştırma yapan çöp toplayıcı

Google I/O'da duyurulduğu gibi, ART, Android 8.0'da yeni bir eşzamanlı kompaktlaştırma çöp toplayıcı (GC) içerir. Bu toplayıcı, GC her çalıştığında ve uygulama çalışırken yığını sıkıştırır. İşleme iş parçacığı kökleri için yalnızca kısa bir duraklama yapılır. Avantajları:

  • GC her zaman yığını sıkıştırır: Android 7.0'a kıyasla ortalama% 32 daha küçük yığın boyutları.
  • Sıkıştırma, iş parçacığı yerel bump işaretçi nesne ayırmayı sağlar: Ayırmalar, Android 7.0'a göre% 70 daha hızlıdır.
  • Android 7.0 GC ile karşılaştırıldığında H2 karşılaştırma testinde% 85 daha kısa duraklatma süreleri sunar.
  • Duraklatma süreleri artık yığın boyutuyla ölçeklenmiyor. Uygulamalar, takılma konusunda endişelenmeden büyük yığınları kullanabilir.
  • GC uygulama ayrıntısı - Okuma engelleri:
    • Okuma engelleri, her nesne alanı okuması için yapılan küçük bir iş miktarıdır.
    • Bunlar derleyicide optimize edilir ancak bazı kullanım alanlarında yavaşlamaya neden olabilir.

Döngü optimizasyonları

Android 8.0 sürümünde ART tarafından çok çeşitli döngü optimizasyonları kullanılır:

  • Sınır kontrolü ortadan kaldırmaları
    • Statik: Aralıkların derleme zamanında sınırlar içinde olduğu kanıtlanmıştır.
    • Dinamik: Çalışma zamanı testleri, döngülerin sınırlar içinde kalmasını sağlar (aksi takdirde optimizasyon kaldırılır).
  • İndüksiyon değişkeni eleme
    • Ölü indüksiyonu kaldırma
    • Yalnızca döngüden sonra kullanılan tümevarımı kapalı biçimdeki ifadelerle değiştirme
  • Döngü gövdesindeki ölü kodun ortadan kaldırılması, ölü hale gelen döngülerin tamamen kaldırılması
  • Mukavemet azaltma
  • Döngü dönüşümleri: tersine çevirme, değiştirme, bölme, açma, unimodüler vb.
  • SIMDization (vektörizasyon olarak da bilinir)

Döngü optimize edici, ART derleyicisinde kendi optimizasyon geçişinde bulunur. Çoğu döngü optimizasyonu, başka yerlerdeki optimizasyon ve basitleştirme işlemlerine benzer. Çoğu CFG yardımcı programı (nodes.h'ye bakın) CFG'yi yeniden yazmaya değil, oluşturmaya odaklandığından, CFG'yi normalden daha ayrıntılı bir şekilde yeniden yazan bazı optimizasyonlarla ilgili sorunlar ortaya çıkar.

Sınıf hiyerarşisi analizi

Android 8.0'daki ART, sınıf hiyerarşilerini analiz ederek oluşturulan bilgilere göre sanal çağrıları doğrudan çağrılara dönüştüren bir derleyici optimizasyonu olan Sınıf Hiyerarşisi Analizi'ni (CHA) kullanır. Sanal aramalar, vtable araması etrafında uygulandıkları ve birkaç bağımlı yükleme yaptıkları için pahalıdır. Ayrıca sanal görüşmeler satır içi olarak eklenemez.

İlgili geliştirmelerin özeti aşağıda verilmiştir:

  • Dinamik tek uygulama yöntemi durumu güncelleme: Sınıf bağlantı süresinin sonunda, vtable doldurulduğunda ART, giriş giriş karşılaştırması yaparak üst sınıfın vtable'ını oluşturur.
  • Derleyici optimizasyonu: Derleyici, bir yöntemin tek uygulama bilgilerinden yararlanır. Bir A.foo yönteminde tek uygulama işareti ayarlanmışsa derleyici, sanal çağrıyı doğrudan çağrıya dönüştürür ve ardından doğrudan çağrıyı satır içine yerleştirmeye çalışır.
  • Derlenmiş kod geçersiz kılma: Tek uygulama bilgileri güncellendiğinde sınıf bağlantısı süresinin sonunda da (A.foo yöntemi daha önce tek uygulamaya sahipken bu durum artık geçersiz kılındıysa) A.foo yönteminin tek uygulamaya sahip olduğu varsayımına dayanan tüm derlenmiş kodların geçersiz kılınması gerekir.
  • Optimizasyonun kaldırılması: Yığında bulunan canlı derlenmiş kod için, geçersiz kılınan derlenmiş kodu yorumlayıcı moduna zorlayarak doğruluğu garanti etmek amacıyla optimizasyonun kaldırılması işlemi başlatılır. Eşzamanlı ve eşzamansız iyileştirme kaldırma işlemlerinin bir karışımı olan yeni bir iyileştirme kaldırma mekanizması kullanılacak.

.oat dosyalarındaki satır içi önbellekler

ART artık satır içi önbellekler kullanıyor ve yeterli verinin bulunduğu çağrı sitelerini optimize ediyor. Satır içi önbellekler özelliği, profillere ek çalışma zamanı bilgileri kaydeder ve bunları, önceden derlemeye dinamik optimizasyonlar eklemek için kullanır.

Dexlayout

Dexlayout, Android 8.0'da dex dosyalarını analiz etmek ve bunları bir profile göre yeniden sıralamak için kullanıma sunulan bir kitaplıktır. Dexlayout, cihazdaki boşta bakım derlemesi sırasında dex dosyasının bölümlerini yeniden sıralamak için çalışma zamanı profili oluşturma bilgilerini kullanmayı amaçlar. Sık erişilen dex dosyasının bölümlerini birlikte gruplandırarak programlar, yerelliğin iyileştirilmesi sayesinde daha iyi bellek erişim kalıplarına sahip olabilir. Bu sayede RAM tasarrufu sağlanır ve başlatma süresi kısalır.

Profil bilgileri şu anda yalnızca uygulamalar çalıştırıldıktan sonra kullanılabildiğinden dexlayout, boşta bakım sırasında dex2oat'in cihaz üzerinde derlemesine entegre edilir.

Dex önbelleğini kaldırma

Android 7.0'a kadar DexCache nesnesi, DexFile'daki belirli öğelerin sayısıyla orantılı olarak dört büyük diziye sahipti. Bu diziler şunlardı:

  • dizeler (DexFile::StringId başına bir referans),
  • türler (DexFile::TypeId başına bir referans),
  • yöntemler (DexFile::MethodId başına bir yerel işaretçi),
  • alanları (DexFile::FieldId başına bir yerel işaretçi).

Bu diziler, daha önce çözdüğümüz nesnelerin hızlıca alınması için kullanılıyordu. Android 8.0'da yöntemler dizisi hariç tüm diziler kaldırıldı.

Çevirmen performansı

Android 7.0 sürümünde, "mterp" adlı bir yorumlayıcının kullanıma sunulmasıyla yorumlayıcı performansı önemli ölçüde iyileştirildi. Bu yorumlayıcı, makine dilinde yazılmış temel bir getirme/kod çözme/yorum mekanizmasına sahiptir. Mterp, hızlı Dalvik yorumlayıcısı temel alınarak modellenmiştir ve arm, arm64, x86, x86_64, mips ve mips64'ü destekler. Art'ın mterp'i, hesaplama kodu için Dalvik'in hızlı yorumlayıcısıyla yaklaşık olarak karşılaştırılabilir. Ancak bazı durumlarda bu süre önemli ölçüde, hatta çok daha uzun olabilir:

  1. Performansı çağırma
  2. Dizeleri değiştirme ve Dalvik'te yerleşik olarak tanınan yöntemleri yoğun şekilde kullanan diğer işlemler.
  3. Daha yüksek yığın bellek kullanımı.

Android 8.0 bu sorunları giderir.

Daha fazla satır içi reklam

Android 6.0'dan beri ART, aynı dex dosyalarındaki tüm çağrıları satır içine yerleştirebilir ancak farklı dex dosyalarındaki yalnızca yaprak yöntemlerini satır içine yerleştirebilir. Bu sınırlamanın iki nedeni vardı:

  1. Başka bir dex dosyasından satır içi yapma işlemi, aynı dex dosyasında satır içi yapma işleminden farklı olarak söz konusu dex dosyasının dex önbelleğinin kullanılmasını gerektirir. Aynı dex dosyasında satır içi yapma işleminde ise yalnızca arayanın dex önbelleği yeniden kullanılabilir. Dex önbelleği, derlenmiş kodda statik çağrılar, dize yükleme veya sınıf yükleme gibi birkaç talimat için gereklidir.
  2. Yığın haritaları yalnızca mevcut dex dosyasındaki bir yöntem dizinini kodluyor.

Bu sınırlamaları gidermek için Android 8.0:

  1. Derlenmiş koddan dex önbelleği erişimini kaldırır (ayrıca "Dex önbelleği kaldırma" bölümüne bakın).
  2. Yığın haritası kodlamasını genişletir.

Senkronizasyon iyileştirmeleri

ART ekibi, MonitorEnter/MonitorExit kod yollarını ayarladı ve ARMv8'de geleneksel bellek bariyerlerine olan bağımlılığımızı azaltarak mümkün olan yerlerde bunları daha yeni (edinme/serbest bırakma) talimatlarla değiştirdi.

Daha hızlı yerel yöntemler

@FastNative ve @CriticalNative ek açıklamaları kullanılarak Java Native Interface'e (JNI) daha hızlı yerel çağrılar yapılabilir. Bu yerleşik ART çalışma zamanı optimizasyonları, JNI geçişlerini hızlandırır ve artık kullanımdan kaldırılan !bang JNI gösteriminin yerini alır. Açıklamalar yerel olmayan yöntemleri etkilemez ve yalnızca bootclasspath (Play Store güncellemeleri yok) üzerindeki platform Java Dil kodu için kullanılabilir.

@FastNative ek açıklaması, statik olmayan yöntemleri destekler. Bir yöntem, parametre veya dönüş değeri olarak jobject öğesine erişiyorsa bunu kullanın.

@CriticalNative ek açıklaması, aşağıdaki kısıtlamalarla yerel yöntemleri çalıştırmak için daha da hızlı bir yol sağlar:

  • Yöntemler statik olmalıdır. Parametreler, dönüş değerleri veya örtülü bir this için nesne olmamalıdır.
  • Yerel yönteme yalnızca temel türler iletilir.
  • Yerel yöntemin işlev tanımında JNIEnv ve jclass parametreleri kullanılmaz.
  • Yöntem, dinamik JNI bağlantısına güvenmek yerine RegisterNatives ile kaydedilmelidir.

@FastNative, yerel yöntem performansını 3 kata kadar, @CriticalNative ise 5 kata kadar artırabilir. Örneğin, Nexus 6P cihazında ölçülen bir JNI geçişi:

Java Native Interface (JNI) çağrısı Yürütme süresi (nanosaniye cinsinden)
Normal JNI 115)
!bang JNI 60
@FastNative 35
@CriticalNative 25