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 atık toplayıcısı

Google I/O'da duyurulduğu gibi, ART, Android 8.0'da yeni bir eşzamanlı sıkış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 olur. 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ığına özel bump işaretçi nesne ayırmayı etkinleştirir: 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 testi için% 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ıtlanı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ştirin.
  • Döngü gövdesindeki ölü kodun kaldırılması, ölü hale gelen döngülerin tamamen kaldırılması
  • Güçlülük azaltma
  • Döngü dönüşümleri: tersine çevirme, değiştirme, bölme, açma, unimodüler vb.
  • SIMDlaştırma (vektörleştirme olarak da adlandırılır)

Döngü optimize edici, ART derleyicisinde kendi optimizasyon geçişinde bulunur. Çoğu döngü optimizasyonu, başka yerlerdeki optimizasyonlara ve basitleştirmelere 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ğlama süresinin sonunda, vtable doldurulduğunda ART, giriş giriş karşılaştırması yaparak üst sınıfın vtable'ını karşılaştırır.
  • Derleyici optimizasyonu: Derleyici, bir yöntemin tek uygulama bilgilerinden yararlanır. Bir A.foo yöntemi için 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 uygulamalı bilgiler güncellendiğinde sınıf bağlantısı süresinin sonunda da (A.foo yöntemi daha önce tek uygulamalıydı ancak bu durum artık geçersiz kılındıysa) A.foo yönteminin tek uygulamalı 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ş kodun yorumlayıcı moduna zorlanarak doğruluğun garanti edilmesi amacıyla optimizasyon kaldırı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 bir profile göre yeniden sıralamak için kullanıma sunulan bir kitaplıktır. Dexlayout, cihazda boşta bakım derlemesi sırasında dex dosyasının bölümlerini yeniden sıralamak için çalışma zamanı profil oluşturma bilgilerini kullanmayı amaçlar. Sık erişilen dex dosyasının bölümlerini 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'ın cihaz üzerinde derleme işlemine 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, derleme dilinde yazılmış temel bir getirme/kod çözme/yorum mekanizmasına sahip bir yorumlayıcı olan "mterp"in kullanıma sunulmasıyla yorumlayıcı performansı önemli ölçüde iyileştirildi. 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 işlem önemli ölçüde, hatta çok daha yavaş olabilir:

  1. Performansı çağırma
  2. Dizeleri değiştirme ve Dalvik'te yerleşik özellikler 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 ekleme, aynı dex dosyasından satır içi eklemenin aksine, bu diğer dex dosyasının dex önbelleğinin kullanılmasını gerektirir. Aynı dex dosyasından satır içi ekleme, yalnızca arayanın dex önbelleğini yeniden kullanabilir. 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ğini kaldırma" bölümüne de 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 engellerine 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 notasyonunun yerini alır. Ek açıklamaların yerel olmayan yöntemler üzerinde etkisi yoktur 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, jobject öğesine parametre veya dönüş değeri olarak erişiyorsa bunu kullanın.

@CriticalNative ek açıklaması, aşağıdaki kısıtlamalarla yerel yöntemleri daha hızlı çalıştırmanın bir yolunu sunar:

  • 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)
Normal JNI 115)
!bang JNI 60
@FastNative 35
@CriticalNative 25