systrace, Android cihaz performansını analiz etmek için kullanılan birincil araçtır. Ancak aslında diğer araçlar için bir sarmalayıcıdır. Kullanıcı alanı izlemeyi kontrol eden ve ftrace'i ayarlayan cihaz tarafında yürütülebilir olan atrace'in etrafındaki ana makine tarafı sarmalayıcı ve Linux çekirdeğinde birincil izleme mekanizmasıdır. systrace, izlemeyi etkinleştirmek için atrace'i kullanır, ardından ftrace arabelleğini okur ve hepsini kendi kendine yeten bir HTML görüntüleyiciye sarmalar. (Daha yeni çekirdeklerde Linux Gelişmiş Berkeley Paket Filtresi (eBPF) desteği olsa da Pixel/Pixel XL'de kullanılan 3.18 çekirdeği (eFPF yok) olduğundan aşağıdaki dokümanlar bu çekirdeğe aittir.)
Google Android ve Google Chrome ekiplerine ait olan systrace, Catapult projesi kapsamında açık kaynaktır. Catapult, systrace'e ek olarak diğer faydalı yardımcı programları da içerir. Örneğin, ftrace, systrace veya atrace tarafından doğrudan etkinleştirilebilecekten daha fazla özelliğe sahiptir ve performans sorunlarında hata ayıklama için kritik olan bazı gelişmiş işlevler içerir. (Bu özellikler için kök erişimi ve genellikle yeni bir çekirdek gerekir.)
systrace'i çalıştırma
Pixel/Pixel XL'de jitter'de hata ayıklama yaparken aşağıdaki komutla başlayın:
./systrace.py sched freq idle am wm gfx view sync binder_driver irq workq input -b 96000
Bu, GPU ve ekran ardışık düzeni etkinliği için gereken ek izleme noktalarıyla birlikte kullanıldığında kullanıcı girişinden ekranda görüntülenen çerçeveye kadar izleme yapmanıza olanak tanır. Etkinliklerin kaybolmasını önlemek için arabellek boyutunu büyük bir değere ayarlayın (büyük bir arabellek olmadan bazı CPU'lar izlemedeki bir noktadan sonra etkinlik içermez).
systrace'i incelerken her etkinliğin CPU'daki bir şey tarafından tetiklendiğini unutmayın.
systrace, ftrace üzerine inşa edildiğinden ve ftrace CPU'da çalıştığından, donanım değişikliklerini günlüğe kaydeden ftrace arabelleğini CPU'daki bir şey yazmalıdır. Yani, bir görüntüleme çitinin neden durum değiştirdiğini merak ediyorsanız geçişin tam noktasında CPU'da nelerin çalıştığını görebilirsiniz (CPU'da çalışan bir şey, günlükte bu değişikliği tetiklemiştir). Bu kavram, systrace'i kullanarak performansı analiz etmenin temelini oluşturur.
Örnek: Çalışma çerçevesi
Bu örnekte, normal bir kullanıcı arayüzü ardışık düzeni için bir systrace açıklanmaktadır. Örneği takip etmek için izlerin zip dosyasını indirin (bu bölümde bahsedilen diğer izler de bu dosyadadır), dosyayı açın ve systrace_tutorial.html
dosyasını tarayıcınızda açın. Bu systrace'in büyük bir dosya olduğunu unutmayın. Günlük işinizde systrace kullanmıyorsanız bu, daha önce tek bir izlemede gördüğünüzden çok daha fazla bilgiye sahip olan büyük bir izleme olabilir.
TouchLatency gibi tutarlı ve düzenli bir iş yükü için kullanıcı arayüzü ardışık düzeni şunları içerir:
- SurfaceFlinger'daki EventThread, uygulama kullanıcı arayüzü iş parçacığını uyandırarak yeni bir kare oluşturma zamanının geldiğini bildirir.
- Uygulama, CPU ve GPU kaynaklarını kullanarak kullanıcı arayüzü iş parçacığında, RenderThread'da ve hwuiTasks'de bir kare oluşturur. Bu, kullanıcı arayüzü için harcanan kapasitenin büyük bir kısmıdır.
- Uygulama, oluşturulan kareyi bir bağlayıcı kullanarak SurfaceFlinger'a gönderir ve ardından SurfaceFlinger uykuya geçer.
- SurfaceFlinger'daki ikinci bir EventThread, SurfaceFlinger'ı uyandırarak derlemeyi ve görüntü çıkışını tetikler. SurfaceFlinger, yapılacak iş olmadığını belirlerse tekrar uykuya geçer.
- SurfaceFlinger, donanım derleyici (HWC)/donanım derleyici 2 (HWC2) veya GL'yi kullanarak kompozisyonu yönetir. HWC/HWC2 bileşimi daha hızlı ve daha düşük güç tüketimine sahiptir ancak çip üzerindeki sisteme (SoC) bağlı sınırlamaları vardır. Bu işlem genellikle yaklaşık 4-6 ms sürer ancak Android uygulamaları her zaman üçlü arabelleğe alındığından 2. adımla çakışma ihtimali vardır. (Uygulamalar her zaman üçlü arabelleğe alınmış olsa da SurfaceFlinger'da bekleyen tek bir kare olabilir. Bu da çift arabelleğe alma ile aynı görünmesine neden olur.)
- SurfaceFlinger, nihai çıkışı bir tedarikçi sürücüsüyle ekrana gönderir ve EventThread'ın uyandırılmasını bekleyerek tekrar uykuya geçer.
15.409 ms'den itibaren kareyi inceleyelim:

1. Şekil, normal çerçevelerle çevrili normal bir çerçevedir. Bu nedenle, kullanıcı arayüzü ardışık düzeninin işleyiş şeklini anlamak için iyi bir başlangıç noktasıdır. TouchLatency için kullanıcı arayüzü mesaj dizisi satırı, farklı zamanlarda farklı renkler içerir. Çubuklar, ileti dizisinin farklı durumlarını gösterir:
- Gri. Uyku.
- Mavi. Çalıştırılabilir (çalıştırılabilir ancak planlayıcı henüz çalıştırılacak olarak seçmedi).
- Yeşil. Etkin olarak çalışıyor (planlayıcı, çalışıyor olduğunu düşünüyor).
- Kırmızı. Kesintiye uğramayan uyku (genellikle çekirdekteki bir kilitte uyku). G/Ç yükünü gösterebilir. Performans sorunlarını ayıklamak için son derece kullanışlıdır.
- Turuncu. G/Ç yükü nedeniyle kesintisiz uyku.
Kesintiye uğramayan uyku nedenini görüntülemek için (sched_blocked_reason
izleme noktasından kullanılabilir) kırmızı kesintisiz uyku dilimini seçin.
EventThread çalışırken TouchLatency için kullanıcı arayüzü iş parçacığı çalıştırılabilir hale gelir. Nelerin uyandırdığını görmek için mavi bölümü tıklayın.

Şekil 2'de, TouchLatency kullanıcı arayüzü iş parçacığının EventThread'a karşılık gelen 6843 iş parçacığı tarafından uyandırıldığı gösterilmektedir. Kullanıcı arayüzü iş parçacığı uyanır, bir kare oluşturur ve SurfaceFlinger'ın kullanması için sıraya ekler.

Bir izlemede binder_driver
etiketi etkinse ilgili işlemde yer alan tüm işlemlerle ilgili bilgileri görüntülemek için bir bağlayıcı işlemi seçebilirsiniz.

Şekil 4'te, 15.423,65 ms'de SurfaceFlinger'daki Binder:6832_1'in, TouchLatency'nin RenderThread'ı olan 9579 iş parçacığı nedeniyle çalışabilir hale geldiği gösterilmektedir. Ayrıca, bağlayıcı işleminin her iki tarafında da queueBuffer'ı görebilirsiniz.
SurfaceFlinger tarafındaki queueBuffer sırasında, TouchLatency'ten bekleyen kare sayısı 1'den 2'ye çıkar.

Şekil 5'te, iki karenin tamamlandığı ve uygulamanın üçüncü kareyi oluşturmaya başlayacağı üçlü arabelleğe alma gösterilmektedir. Bunun nedeni, bazı kareleri atlamış olmamızdır. Bu nedenle uygulama, daha fazla kare atlamayı önlemek için bir yerine iki bekleyen kare tutar.
Kısa süre sonra, bekleyen eski kareyi ekrana gönderebilmesi için SurfaceFlinger'ın ana iş parçacığı ikinci bir EventThread tarafından uyandırılır:

SurfaceFlinger önce bekleyen eski arabelleği sabitler. Bu işlem, bekleyen arabellek sayısının 2'den 1'e düşmesine neden olur.

SurfaceFlinger, arabelleği kilitledikten sonra kompozisyonu ayarlar ve son kareyi ekrana gönderir. (Bu bölümlerin bazıları mdss
izleme noktası kapsamında etkinleştirildiğinden SoC'nize dahil edilmeyebilir.)

Ardından mdss_fb0
, CPU 0'da uyanır. mdss_fb0
, oluşturulan bir kareyi ekrana göndermek için görüntü ardışık düzeninin çekirdek iş parçacığıdır.
mdss_fb0
, izlemede kendi satırı olarak görülebilir (görüntülemek için aşağı kaydırın).

mdss_fb0
uyanır, kısa süre çalışır, kesintisiz uykuya girer ve tekrar uyanır.
Örnek: Çalışmayan çerçeve
Bu örnekte, Pixel/Pixel XL titreme sorunuyla ilgili hata ayıklama işleminde kullanılan bir systrace açıklanmaktadır. Örneği takip etmek için izlerin zip dosyasını indirin (bu bölümde bahsedilen diğer izleri içerir), dosyanın sıkıştırmasını açın ve systrace_tutorial.html
dosyasını tarayıcınızda açın.
systrace'i açtığınızda aşağıdakine benzer bir görünüm görürsünüz:

Takılma olup olmadığını kontrol ederken SurfaceFlinger altındaki FrameMissed satırını kontrol edin.
FrameMissed, HWC2 tarafından sağlanan bir yaşam kalitesi iyileştirmesidir. Diğer cihazlar için systrace'i görüntülerken cihaz HWC2 kullanmıyorsa FrameMissed satırı mevcut olmayabilir. Her iki durumda da FrameMissed, SurfaceFlinger'ın son derece düzenli çalışma zamanlarından birini kaçırması ve vsync'te uygulama için bekleyen arabellek sayısının değişmemesiyle ilişkilidir (com.prefabulated.touchlatency
).

Şekil 11'de 15598,29&nbps;ms'de kaçırılan bir kare gösterilmektedir.SurfaceFlinger, vsync aralığında kısa bir süre uyandı ve herhangi bir işlem yapmadan tekrar uykuya daldı. Bu, SurfaceFlinger'ın ekrana tekrar kare göndermeye çalışmanın değmeyeceğine karar verdiği anlamına gelir. Neden?
Bu kare için ardışık düzenin nasıl parçalara ayrıldığını anlamak üzere, normal bir kullanıcı arayüzü ardışık düzeninin systrace'de nasıl göründüğünü görmek için önce yukarıdaki çalışan kare örneğini inceleyin. Hazır olduğunuzda, kaçırdığınız kareye dönün ve geriye doğru ilerleyin. SurfaceFlinger'ın uyandığı ve hemen uykuya daldığına dikkat edin. TouchLatency kaynağından bekleyen karelerin sayısını görüntülerken iki kare vardır (ne olduğunu anlamanıza yardımcı olacak iyi bir ipucu).

SurfaceFlinger'da çerçevelerimiz olduğu için bu bir uygulama sorunu değildir. Ayrıca SurfaceFlinger doğru zamanda uyanıyor. Dolayısıyla bu bir SurfaceFlinger sorunu değil. Hem SurfaceFlinger hem de uygulama normal görünüyorsa sorun büyük olasılıkla sürücüden kaynaklanmaktadır.
mdss
ve sync
izleme noktaları etkinleştirildiğinden, çerçevelerin ekrana ne zaman gönderildiğini kontrol eden çitler (ekran sürücüsü ile SurfaceFlinger arasında paylaşılır) hakkında bilgi edinebiliriz.
Bu çitler, ekranda bir çerçevenin gösterildiğini belirten mdss_fb0_retire
altında listelenir. Bu çitler, sync
izleme kategorisinin bir parçası olarak sağlanır. Hangi çitlerin SurfaceFlinger'daki belirli etkinliklere karşılık geldiği SOC'nize ve sürücü yığınınıza bağlıdır. Bu nedenle, izlemelerinizdeki çit kategorilerinin anlamını anlamak için SOC tedarikçinizle birlikte çalışın.

Şekil 13'te, beklendiği gibi 16,7 ms değil 33 ms boyunca görüntülenen bir kare gösterilmektedir. Bu dilimin yarısında, bu kare yeni bir kareyle değiştirilmiş olmalıydı ancak değiştirilmedi. Önceki kareyi görüntüleyip istediğiniz şeyi arayın.

Şekil 14'te kare başına 14.482 ms gösterilmektedir. İki karelik kesinti 33,6 ms. idi. Bu, iki kare için bekleyeceğimize yakın bir değerdir (kare başına 60 Hz, 16,7 ms. olarak oluşturuyoruz). Ancak 14.482 ms, 16,7 ms'ye hiç yakın değil.Bu da ekran borusunda çok ciddi bir sorun olduğunu gösteriyor.
Çitin tam olarak nerede bittiğini inceleyerek neyin kontrol ettiğini belirleyin.

İş havuzu, çit değiştiğinde çalışan __vsync_retire_work_handler
içerir. Çekirdek kaynağına baktığınızda bunun ekran sürücüsünün bir parçası olduğunu görebilirsiniz. Görüntülü reklam ardışık düzeni için kritik yolda olduğu anlaşılıyor. Bu nedenle, mümkün olduğunca hızlı çalışmalıdır. Yaklaşık 70 mikrosaniye boyunca çalıştırılabilir (uzun bir planlama gecikmesi değildir), ancak iş havuzu olduğundan doğru şekilde planlanmayabilir.
Bunun neden olup olmadığını belirlemek için önceki kareyi kontrol edin. Bazen titreme zaman içinde birikebilir ve sonunda son tarihin kaçırılmasına neden olabilir.

Görüntüleme ardışık düzeninin kritik yolunun bir kısmı için 2,3 ms planlayıcı gecikmesi kötü bir durumdur.Bu durum, kworker'daki çalıştırılabilir satır seçildiğinde izleyici tarafından beyaza çevrildiği için görünmez ancak istatistikler durumu gösterir.
Devam etmeden önce, görüntüleme ardışık düzeninin kritik yolunun bu bölümünü bir iş işleyicisinden (SCHED_OTHER
CFS iş parçacığı olarak çalışır) özel bir SCHED_FIFO
kiş parçasına taşıyarak gecikmeyi düzeltin. Bu işlev için iş sıralarının sağlayamayacağı (ve sağlamaması gereken) zamanlama garantileri gerekir.
Is this the reason for the jank? Kesin bir şey söylemek zor. Teşhisi kolay olan durumlar (ör. ekran için kritik olan iş parçacıklarının uykuya gitmesine neden olan çekirdek kilidi anlaşmazlığı) dışında, izlemeler genellikle sorunu belirtmez. Bu titreme, kare atlamanın nedeni olabilir mi? Kesinlikle evet. Çit süreleri 16, 7 ms olmalıdır ancak atlanan kareye kadarki karelerde bu süreye hiç yaklaşılmamıştır. Ekran ardışık düzeninin ne kadar sıkı bir şekilde bağlandığı göz önüne alındığında, çit zamanlamaları etrafındaki titremenin bir karenin atlanmasına neden olması mümkündür.
Bu örnekte çözüm, __vsync_retire_work_handler
'ü iş havuzundan özel bir kthread'e dönüştürmeyi içeriyordu. Bu sayede, sıçrayan top testinde belirgin bir titreme iyileştirmesi ve sarsıntı azaltımı elde edildi. Sonraki izlemlerde, 16,7 ms'ye çok yakın olan çit zamanlamaları gösterilmektedir.