Başlatma sürelerini optimize et

Bu dokümanda, belirli cihazlar için başlatma sürelerini iyileştirme konusunda iş ortağı rehberliği sağlanmaktadır. Android cihazlar. Önyükleme süresi, sistem performansının önemli bir bileşenidir, Kullanıcıların cihazı kullanabilmesi için başlatmanın tamamlanmasını beklemesi gerekir. Cihazlar için Soğuk başlatmanın daha sık gerçekleştiği arabalar, hızlı başlatma sistemi zaman çok önemlidir (hiç kimse bir şeyi girmek için onlarca saniye navigasyon hedefi).

Android 8.0, çeşitli iyileştirmeleri destekleyerek başlatma sürelerini kısaltır çeşitli bileşenlerde kullanılabilir. Aşağıdaki tabloda bu performansın iyileştirmeler (Google Pixel ve Pixel XL cihazlarda ölçüldüğü üzere).

Bileşen İyileştirme
Önyükleyici
  • UART günlüğü kaldırılarak 1,6 sn.kaydedildi
  • GZIP'ten LZ4'e geçerek 0,4 sn.tasarruf etti
Cihaz çekirdeği
  • Kullanılmayan çekirdek yapılandırmalarını kaldırıp sürücü boyutunu küçülterek 0,3 saniye tasarruf edildi
  • Dm-verity önceden getirme optimizasyonu ile 0,3 sn.tasarruf edildi
  • Sürücüdeki gereksiz bekleme/testi kaldırmak için 0,15 sn.kaydedildi
  • CONFIG_CC_OPTIMIZE_FOR_SIZE kaldırmak için 0,12 sn.kaydedildi
G/Ç ayarı
  • Normal başlatmada 2 sn. kaydedildi
  • İlk başlatmada 25 sn. tasarruf edildi
init.*.rc
  • init komutlarını paralel yaparak 1,5 sn.tasarruf edildi
  • zygot erken başlayarak 0,25 sn.tasarruf edildi
  • cpuset tune ile 0,22 sn.tasarruf edildi
Açılış animasyonu
  • 2 sn. önce fsck tetiklenmeden açılışta başladı, fsck tetiklendi
  • Açılış animasyonu hemen kapanarak Pixel XL'de 5 sn. kaydedildi
SELinux politikası genfscon tarafından tarihinde 0,2 sn.kaydedildi

Bootloader'ı optimize edin

Bootloader'ı daha iyi önyükleme süreleri için optimize etmek üzere:

  • Günlük kaydı için:
    • Çok sayıda işlem yapılması uzun sürebileceğinden UART'a günlük yazma özelliğini devre dışı bırakın günlük kaydı. (Google Pixel cihazlarda, bootloader'ı 1,5 sn.yavaşlattığını tespit ettik).
    • Sadece hata durumlarını günlüğe kaydedin ve diğer bilgileri belleğe almayı düşünün ayrı bir mekanizmaya sahip.
  • Çekirdek sıkıştırmasını açmak için modern donanımlarda LZ4 kullanmayı düşünebilirsiniz. (örneğin, yama) yükleyebilirsiniz. Gelecekteki farklı çekirdek sıkıştırması seçeneklerinin yüklenmesi farklı olabilir ve zaman alır. Ayrıca, klavyenizde bazı seçenekler diğerlerinden daha iyi gereken donanımları.
  • Geri döndürme/özel mod girişi için gereksiz bekleme sürelerini kontrol edin ve gerekir.
  • Bootloader'da harcanan başlatma süresini, çekirdeğe cmdline olarak iletin.
  • CPU saatini kontrol edin ve paralel yapmayı göz önünde bulundurun (çok çekirdekli destek gerektirir) ilk kullanıma hazırlamayı da kolaylaştırır.

G/Ç verimliliğini optimize et

G/Ç verimliliğini artırmak, cihazın açılma süresini hızlandırmak ve gerekli olmayan hiçbir şey (Google Pixel açılışta yaklaşık 1,2 GB'lık veri okunur).

Dosya sistemini ayarlama

Önceden okunan Linux çekirdeği, bir dosya baştan okunduğunda veya bloklar sıralı olarak okunur, bu da G/Ç planlayıcısının ayarlanmasını gerektirir (farklı bir iş yüküne sahip olan başlatma işlemi) için özel olarak karakteristikleştirmesine yardımcı olur.

Sorunsuz (A/B) güncellemeleri destekleyen cihazlar dosya sisteminden büyük yarar sağlar ilk başlatma sırasında ince ayar (ör.Google Pixel'de 20 sn.). Bir örnek verelim. Google Pixel için aşağıdaki parametreler:

on late-fs
  # boot time fs tune
    # boot time fs tune
    write /sys/block/sda/queue/iostats 0
    write /sys/block/sda/queue/scheduler cfq
    write /sys/block/sda/queue/iosched/slice_idle 0
    write /sys/block/sda/queue/read_ahead_kb 2048
    write /sys/block/sda/queue/nr_requests 256
    write /sys/block/dm-0/queue/read_ahead_kb 2048
    write /sys/block/dm-1/queue/read_ahead_kb 2048

on property:sys.boot_completed=1
    # end boot time fs tune
    write /sys/block/sda/queue/read_ahead_kb 512
    ...

Çeşitli

  • Çekirdek yapılandırmasını kullanarak dm-verity karma önceden getirme boyutunu etkinleştirme DM_VERITY_HASH_PREFETCH_MIN_SIZE (varsayılan boyut 128'dir).
  • Daha iyi dosya sistemi kararlılığı ve her önyüklemede TARGET_USES_MKE2FS'yi ayarlayarak yeni ext4 oluşturma aracını kullanın BoardConfig.mk.

G/Ç analizi

Başlatma sırasında G/Ç etkinliklerini anlamak için çekirdek ftrace verilerini (ayrıca sistem izleme):

trace_event=block,ext4 in BOARD_KERNEL_CMDLINE

Her bir dosyanın dosya erişiminin dökümünü almak için çekirdekte aşağıdaki değişiklikleri yapın (yalnızca geliştirme çekirdeği; üretim çekirdeklerinde kullanmayın):

diff --git a/fs/open.c b/fs/open.c
index 1651f35..a808093 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -981,6 +981,25 @@
 }
 EXPORT_SYMBOL(file_open_root);
 
+static void _trace_do_sys_open(struct file *filp, int flags, int mode, long fd)
+{
+       char *buf;
+       char *fname;
+
+       buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+       if (!buf)
+               return;
+       fname = d_path(&filp-<f_path, buf, PAGE_SIZE);
+
+       if (IS_ERR(fname))
+               goto out;
+
+       trace_printk("%s: open(\"%s\", %d, %d) fd = %ld, inode = %ld\n",
+                     current-<comm, fname, flags, mode, fd, filp-<f_inode-<i_ino);
+out:
+       kfree(buf);
+}
+
long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
 {
 	struct open_flags op;
@@ -1003,6 +1022,7 @@
 		} else {
 			fsnotify_open(f);
 			fd_install(fd, f);
+			_trace_do_sys_open(f, flags, mode, fd);

Başlatma performansını analiz etmeye yardımcı olması için aşağıdaki komut dosyalarını kullanın.

  • system/extras/boottime_tools/bootanalyze/bootanalyze.py. Başlatma işlemindeki önemli adımların dökümü ile başlatma süresini ölçer.
  • system/extras/boottime_tools/io_analysis/check_file_read.py boot_trace Her dosya için erişim bilgileri sağlar.
  • system/extras/boottime_tools/io_analysis/check_io_trace_all.py boot_trace Sistem düzeyinde döküm verir.

Init.*.rc'yi optimize edin

Başlangıç, çekirdekten çerçevenin kurulmasına kadar uzanan köprüdür ve cihazlar genellikle farklı başlangıç aşamalarında birkaç saniye harcar.

Görevleri paralel olarak yürütme

Mevcut Android başlangıcı aşağı yukarı tek iş parçacıklı bir işlem olsa da birbirine paralel olarak bazı görevleri

  • Bir kabuk komut dosyası hizmetinde yavaş komutlar yürütün ve bu komutlara daha sonra belirli bir mülk bekleniyor. Android 8.0, bu kullanım alanını yeni bir wait_for_property komutudur.
  • Başlangıçtaki yavaş işlemleri tanımlama. Sistem, init komutunu günlüğe kaydeder exec/wait_for_prop veya uzun süren herhangi bir işlem (Android 8.0'da, herhangi bir komut 50 ms'den fazla sürdüğünü unutmayın). Örnek:
    init: Command 'wait_for_coldboot_done' action=wait_for_coldboot_done returned 0 took 585.012ms
    .

    Bu günlüğün incelenmesi, iyileştirme fırsatları olduğunu gösterebilir.

  • Hizmetleri hemen başlatın ve kritik yoldaki çevre birimi cihazlarını erkenden etkinleştirin. Örneğin, Örneğin, bazı SOC'ler, başlamadan önce güvenlikle ilgili hizmetlerin başlatılmasını gerektirir. SurfaceFlinger'ı kullanabilirsiniz. ServiceManager "wait for" (şunu bekle:) değerini döndürdüğünde sistem günlüğünü inceleyin hizmet" Bu genellikle bağımlı bir hizmetin başlatılması gerektiğini gösterir. tıklayın.
  • init.*.rc dosyasındaki kullanılmayan hizmetleri ve komutları kaldırın. Şu projede kullanılmayan herhangi bir şey: erken aşamadaki başlatma işlemi, başlatmanın tamamlanmasına ertelenmelidir.

Not: Mülk hizmeti, başlangıç sürecinin bir parçasıdır. Bu nedenle, Başlatma sırasında setproperty, başlatma sırasında meşgulse uzun gecikmeye neden olabilir yerleşik komutlar vardır.

Planlayıcı ayarını kullanma

Erken başlatma için planlayıcı ayarını kullan. Google Pixel örneği:

on init
    # boottime stune
    write /dev/stune/schedtune.prefer_idle 1
    write /dev/stune/schedtune.boost 100
    on property:sys.boot_completed=1
    # reset stune
    write /dev/stune/schedtune.prefer_idle 0
    write /dev/stune/schedtune.boost 0

    # or just disable EAS during boot
    on init
    write /sys/kernel/debug/sched_features NO_ENERGY_AWARE
    on property:sys.boot_completed=1
    write /sys/kernel/debug/sched_features ENERGY_AWARE

Bazı hizmetlerin başlatma sırasında öncelik artırılması gerekebilir. Örnek:

init.zygote64.rc:
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
    class main
    priority -20
    user root
...

Ziggota erken başlayın

Dosya tabanlı şifrelemeye sahip cihazlar, zigotun başlangıcında zygot'u daha erken başlatabilir tetikleyici (varsayılan olarak, zygote sınıfının ana sürümünde başlatılır. Bu, zygote-start) ifade eder. Bunu yaparken zigotun tüm CPU'larda çalışmasına izin verdiğinizden emin olun (örn., yanlış cpuset ayarı, zigot'u belirli CPU'larda çalışmaya zorlayabilir).

Güç tasarrufunu devre dışı bırak

Cihaz önyüklemesi sırasında UFS ve/veya CPU gibi bileşenler için güç tasarrufu ayarı devre dışı bırakılabilir.

Dikkat: Güç tasarrufu özelliğinin etkinleştirilmesi gerekir: şarj modunu kullanmanızı öneririz.

on init
    # Disable UFS powersaving
    write /sys/devices/soc/${ro.boot.bootdevice}/clkscale_enable 0
    write /sys/devices/soc/${ro.boot.bootdevice}/clkgate_enable 0
    write /sys/devices/soc/${ro.boot.bootdevice}/hibern8_on_idle_enable 0
    write /sys/module/lpm_levels/parameters/sleep_disabled Y
on property:sys.boot_completed=1
    # Enable UFS powersaving
    write /sys/devices/soc/${ro.boot.bootdevice}/clkscale_enable 1
    write /sys/devices/soc/${ro.boot.bootdevice}/clkgate_enable 1
    write /sys/devices/soc/${ro.boot.bootdevice}/hibern8_on_idle_enable 1
    write /sys/module/lpm_levels/parameters/sleep_disabled N
on charger
    # Enable UFS powersaving
    write /sys/devices/soc/${ro.boot.bootdevice}/clkscale_enable 1
    write /sys/devices/soc/${ro.boot.bootdevice}/clkgate_enable 1
    write /sys/devices/soc/${ro.boot.bootdevice}/hibern8_on_idle_enable 1
    write /sys/class/typec/port0/port_type sink
    write /sys/module/lpm_levels/parameters/sleep_disabled N

Kritik olmayan başlatma işlemini ertele

ZRAM gibi kritik olmayan başlatma işlemi boot_complete tarihine kadar ertelenebilir.

on property:sys.boot_completed=1
   # Enable ZRAM on boot_complete
   swapon_all /vendor/etc/fstab.${ro.hardware}

Açılış animasyonunu optimize et

Açılış animasyonunu optimize etmek için aşağıdaki ipuçlarından yararlanın.

Erken başlangıcı yapılandır

Android 8.0, açılış animasyonunun kullanıcı verileri eklenmeden önce başlatılabilmesini sağlar bölüm. Ancak, Android 8.0'daki yeni ext4 araç zinciri kullanılırken bile, fsck uyarısı, güvenlik nedeniyle düzenli olarak tetiklenmeye devam eder. Bu da, başlatma hizmetini başlatırlar.

Bootaniasyonun erken başlatılması için fstab ekleme bağlantısını iki aşamaya bölün:

  • Erken aşamada, yalnızca bölümleri (örneğin, Çalıştırma gerektirmeyen system/ ve vendor/) ve bağımlılıklarını (örn. hizmet yöneticisi ve yüzeyflinger).
  • İkinci aşamada, daha sonra isabet alan bölümleri (ör. data/) çalıştırma kontrolleri gerekir.

Açılış animasyonu, ne olursa olsun çok daha hızlı (ve sabit bir fsck'ye dokunun.

Temizle

Çıkış sinyalini aldıktan sonra, başlatmada son kısım olan uzunluk, uzun sürebilir. Kısa sürede başlatılan bir sistemin, uygulamanın uzun süre etkili bir şekilde gizleyebilecek yüksek performanslı animasyonlar. Önerilerimiz: hem tekrar eden döngüyü hem de sonu kısaltabilirsiniz.

SELinux'u optimize edin

SELinux'u optimize ederek önyükleme sürelerini iyileştirmek için aşağıdaki ipuçlarını kullanın.

  • Temiz normal ifadeler (regex) kullanın. Kötü biçimlendirilmiş normal ifade SELinux politikasını file_contexts içinde sys/devices. Örneğin, normal ifade /sys/devices/.*abc.*(/.*)?, yanlışlıkla tümünün taranmasını zorlar "abc" ifadesini içeren /sys/devices alt dizin (eşleşmeleri etkinleştirir) /sys/devices/abc ve /sys/devices/xyz/abc için. Bu normal ifadeyi /sys/devices/[^/]*abc[^/]*(/.*)? olarak geliştirmek şu sonuçları doğurur: yalnızca /sys/devices/abc için bir eşleşmeyi etkinleştir.
  • Etiketleri genfscon'a taşıyın. Bu mevcut SELinux özelliği, dosya eşleştirme ön eklerini SELinux ikili programı; burada çekirdek, bunları çekirdek tarafından oluşturulan dosya sistemleri. Bu, çekirdek tarafından oluşturulan yanlış etiketlenmiş dosyaların düzeltilmesine de yardımcı olur. erişmeye çalışan kullanıcı alanı süreçleri arasında oluşabilecek ırk koşulları bu dosyaları gözden geçirmeniz gerekir.

Araçlar ve yöntemler

Optimizasyon hedefleri için veri toplamanıza yardımcı olması amacıyla aşağıdaki araçları kullanın.

Önyükleme çizelgesi

Önyükleme çizelgesi, bir bütün için tüm işlemlerin CPU ve G/Ç yükü dökümünü sağlar bahsedeceğim. Sistem görüntüsünün yeniden oluşturulmasını gerektirmez ve hızlı bir şekilde kullanılabilir. sisteminizi incelemelisiniz.

Önyükleme şemasını etkinleştirmek için:

adb shell 'touch /data/bootchart/enabled'
adb reboot

Başlatma sonrasında, başlatma grafiğini getir:

$ANDROID_BUILD_TOP/system/core/init/grab-bootchart.sh

İşlemi tamamladığınızda, verilerin toplanmasını önlemek için /data/bootchart/enabled sütununu silin. bu verileri takip edebilirsiniz.

Önyükleme şeması çalışmaz ve bootchart.png olmadığını belirten bir hata alırsanız şu:
  1. Şu komutları çalıştırın:
          sudo apt install python-is-python3
          cd ~/Documents
          git clone https://github.com/xrmx/bootchart.git
          cd bootchart/pybootchartgui
          mv main.py.in main.py
        
    .
  2. $ANDROID_BUILD_TOP/system/core/init/grab-bootchart.sh uygulamasını güncelle pybootchartgui yerel kopyasına işaret etmek için (konum: ~/Documents/bootchart/pybootchartgui.py)

Sistrace

Systrace, başlatma sırasında hem çekirdek hem de Android izlerinin toplanmasına olanak tanır. Sistem izlemenin görselleştirilmesi, başlatabilirsiniz. (Ancak, deneme süresindeki ortalama sayıyı veya birikmiş sayıyı kontrol etmek için çekirdek izlemeye doğrudan bakmak daha kolaydır.

Başlatma sırasında sistem izlemeyi etkinleştirmek için:

  • frameworks/native/cmds/atrace/atrace.rc uygulamasında şu değişikliği yap:
      write /sys/kernel/debug/tracing/tracing_on 0
      write /sys/kernel/tracing/tracing_on 0

    Şunları yapmak için:

      #    write /sys/kernel/debug/tracing/tracing_on 0
      #    write /sys/kernel/tracing/tracing_on 0
  • Bu, izlemeyi etkinleştirir (varsayılan olarak devre dışıdır).

  • device.mk dosyasına aşağıdaki satırı ekleyin:
    PRODUCT_PROPERTY_OVERRIDES +=    debug.atrace.tags.enableflags=802922
    PRODUCT_PROPERTY_OVERRIDES +=    persist.traced.enable=0
  • Cihazdaki BoardConfig.mk dosyasına aşağıdakileri ekleyin:
    BOARD_KERNEL_CMDLINE := ... trace_buf_size=64M trace_event=sched_wakeup,sched_switch,sched_blocked_reason,sched_cpu_hotplug
  • Ayrıntılı G/Ç analizi için block, ext4 ve f2fs öğelerini de ekleyin.

  • Cihaza özel init.rc dosyasına aşağıdakileri ekleyin:
    on property:sys.boot_completed=1          // This stops tracing on boot complete
    write /d/tracing/tracing_on 0
    write /d/tracing/events/ext4/enable 0
    write /d/tracing/events/f2fs/enable 0
    write /d/tracing/events/block/enable 0
    
  • Başlatma sonrasında, şunu getir:

    adb root && adb shell atrace --async_stop -z -c -o /data/local/tmp/boot_trace
    adb pull /data/local/tmp/boot_trace
    $ANDROID_BUILD_TOP/external/chromium-trace/systrace.py --from-file=boot_trace
    
ziyaret edin.