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

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 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ığı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 ortadan kaldırılması, ölü hale gelen döngülerin tamamen kaldırılması
  • Kuvvet azaltma
  • Döngü dönüşümleri: tersine çevirme, değiştirme, bölme, açma, tek modüllü 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 oluşturmaya odaklandığı için 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 aramalar satır içi olarak kullanılamaz.

İlgili geliştirmelerin özeti:

  • 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 bilgisinden 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ş 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 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ı profil 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ı 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 kabaca Dalvik'in hızlı yorumlayıcısıyla 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 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, yalnızca çağıranın dex önbelleğini yeniden kullanabilen başka bir dex dosyasının dex önbelleğinin kullanılmasını gerektirir. 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 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 gösteriminin yerini alır. Açıklamalar, yerel olmayan yöntemleri etkilemez ve yalnızca bootclasspath platformundaki Java dili kodu için kullanılabilir (Play Store güncellemeleri yoktur).

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