Performans testi

Android 8.0, aktarım hızı ve gecikme için bağlayıcı ve hwbinder performans testlerini içerir. Algılanabilir performans sorunlarını tespit etmek için birçok senaryo mevcut olsa da, bu tür senaryoları çalıştırmak zaman alıcı olabilir ve sonuçlar genellikle sistem entegre edilene kadar elde edilemez. Sağlanan performans testlerinin kullanılması, geliştirme sırasında test etmeyi, ciddi sorunları daha erken tespit etmeyi ve kullanıcı deneyimini iyileştirmeyi kolaylaştırır.

Performans testleri aşağıdaki dört kategoriyi içerir:

  • ciltleyici verimi ( system/libhwbinder/vts/performance/Benchmark_binder.cpp mevcuttur)
  • ciltleyici gecikmesi ( frameworks/native/libs/binder/tests/schd-dbg.cpp adresinde mevcuttur)
  • hwbinder verimi ( system/libhwbinder/vts/performance/Benchmark.cpp mevcuttur)
  • hwbinder gecikmesi ( system/libhwbinder/vts/performance/Latency.cpp mevcuttur)

Bağlayıcı ve hwbinder hakkında

Binder ve hwbinder, aynı Linux sürücüsünü paylaşan ancak aşağıdaki niteliksel farklılıklara sahip olan Android süreçler arası iletişim (IPC) altyapılarıdır:

Bakış açısı bağlayıcı bağlayıcı
Amaç Çerçeve için genel amaçlı bir IPC şeması sağlayın Donanımla iletişim kurun
Mülk Android çerçeve kullanımı için optimize edildi Minimum ek yük düşük gecikme süresi
Ön plan/arka plan için planlama politikasını değiştirin Evet HAYIR
Geçen argümanlar Parcel nesnesi tarafından desteklenen serileştirmeyi kullanır Dağılım arabelleklerini kullanır ve Parsel serileştirmesi için gereken verileri kopyalamak için gereken yükü ortadan kaldırır
Öncelikli miras HAYIR Evet

Bağlayıcı ve hwbinder işlemleri

Bir systrace görselleştiricisi işlemleri aşağıdaki gibi görüntüler:

Şekil 1. Bağlayıcı süreçlerin Systrace görselleştirmesi.

Yukarıdaki örnekte:

  • Dört (4) schd-dbg işlemi istemci işlemleridir.
  • Dört (4) ciltleme işlemi sunucu işlemleridir (isim Binder ile başlar ve sıra numarasıyla biter).
  • Bir istemci işlemi her zaman istemcisine ayrılmış bir sunucu işlemiyle eşleştirilir.
  • Tüm istemci-sunucu işlem çiftleri çekirdek tarafından bağımsız olarak eş zamanlı olarak planlanır.

CPU 1'de işletim sistemi çekirdeği, isteği yayınlamak için istemciyi çalıştırır. Daha sonra mümkün olduğunda bir sunucu işlemini uyandırmak, isteği işlemek ve istek tamamlandıktan sonra bağlam geçişini yapmak için aynı CPU'yu kullanır.

Verim ve gecikme

İstemci ve sunucu işlemlerinin sorunsuz bir şekilde değiştiği mükemmel bir işlemde, üretim ve gecikme testleri önemli ölçüde farklı mesajlar üretmez. Bununla birlikte, işletim sistemi çekirdeği donanımdan gelen bir kesme isteğini (IRQ) ele alırken, kilitleri beklerken veya yalnızca bir mesajı hemen işlememeyi seçtiğinde bir gecikme balonu oluşabilir.

Şekil 2. Verim ve gecikme farklılıklarından kaynaklanan gecikme balonu.

Verim testi, farklı yük boyutlarına sahip çok sayıda işlem üreterek normal işlem süresi (en iyi senaryolarda) ve ciltleyicinin elde edebileceği maksimum verim için iyi bir tahmin sağlar.

Buna karşılık gecikme testi, normal işlem süresini en aza indirmek için veri yükü üzerinde hiçbir eylem gerçekleştirmez. İşlem süresini ciltleyici yükünü tahmin etmek, en kötü durum için istatistik oluşturmak ve gecikme süresi belirli bir son tarihe ulaşan işlemlerin oranını hesaplamak için kullanabiliriz.

Öncelikli tersine çevirmeleri yönetin

Önceliği tersine çevirme, daha yüksek önceliğe sahip bir iş parçacığının mantıksal olarak daha düşük önceliğe sahip bir iş parçacığını beklediğinde meydana gelir. Gerçek zamanlı (RT) uygulamalarda önceliklerin tersine çevrilmesi sorunu vardır:

Şekil 3. Gerçek zamanlı uygulamalarda önceliklerin tersine çevrilmesi.

Linux Tamamen Adil Zamanlayıcı (CFS) planlamasını kullanırken, diğer iş parçacıkları daha yüksek önceliğe sahip olsa bile bir iş parçacığının her zaman çalışma şansı vardır. Sonuç olarak, CFS zamanlamasına sahip uygulamalar öncelik ters çevirmeyi bir sorun olarak değil, beklenen davranış olarak ele alır. Bununla birlikte, Android çerçevesinin yüksek öncelikli iş parçacıklarının ayrıcalığını garanti altına almak için RT planlamasına ihtiyaç duyduğu durumlarda, önceliğin tersine çevrilmesi çözümlenmelidir.

Bir ciltleyici işlemi sırasında öncelik ters çevirme örneği (bir ciltleyici iş parçacığının hizmete sunulması beklenirken RT iş parçacığı diğer CFS iş parçacıkları tarafından mantıksal olarak engellenir):

Şekil 4. Önceliğin tersine çevrilmesi, gerçek zamanlı iş parçacıklarının engellenmesi.

Tıkanmaları önlemek için, Binder iş parçacığını bir RT istemcisinden gelen bir isteğe hizmet verdiğinde geçici olarak bir RT iş parçacığına yükseltmek için öncelik devralmayı kullanabilirsiniz. RT planlamasının sınırlı kaynaklara sahip olduğunu ve dikkatli kullanılması gerektiğini unutmayın. N CPU'lu bir sistemde mevcut RT iş parçacıklarının maksimum sayısı da n'dir ; Tüm CPU'lar diğer RT iş parçacıkları tarafından alınırsa ek RT iş parçacıklarının beklemesi (ve dolayısıyla son tarihlerini kaçırması) gerekebilir.

Tüm olası öncelik ters çevirmelerini çözmek için hem bağlayıcı hem de hwbinder için öncelik devralmayı kullanabilirsiniz. Bununla birlikte, ciltleyici sistem genelinde yaygın olarak kullanıldığından, ciltleyici işlemleri için öncelik devralmanın etkinleştirilmesi, sistemin hizmet verebileceğinden daha fazla RT iş parçacığı ile spam yapmasına neden olabilir.

Verimlilik testlerini çalıştırın

Verim testi, bağlayıcı/hwbinder işlem çıktısına karşı gerçekleştirilir. Aşırı yüklenmemiş bir sistemde gecikme kabarcıkları nadirdir ve yineleme sayısı yeterince yüksek olduğu sürece etkileri ortadan kaldırılabilir.

  • Ciltleyici üretim testi system/libhwbinder/vts/performance/Benchmark_binder.cpp dosyasındadır.
  • Hwbinder aktarım hızı testi system/libhwbinder/vts/performance/Benchmark.cpp dosyasındadır.

Test sonuçları

Farklı yük boyutları kullanan işlemler için örnek üretim testi sonuçları:

Benchmark                      Time          CPU           Iterations
---------------------------------------------------------------------
BM_sendVec_binderize/4         70302 ns      32820 ns      21054
BM_sendVec_binderize/8         69974 ns      32700 ns      21296
BM_sendVec_binderize/16        70079 ns      32750 ns      21365
BM_sendVec_binderize/32        69907 ns      32686 ns      21310
BM_sendVec_binderize/64        70338 ns      32810 ns      21398
BM_sendVec_binderize/128       70012 ns      32768 ns      21377
BM_sendVec_binderize/256       69836 ns      32740 ns      21329
BM_sendVec_binderize/512       69986 ns      32830 ns      21296
BM_sendVec_binderize/1024      69714 ns      32757 ns      21319
BM_sendVec_binderize/2k        75002 ns      34520 ns      20305
BM_sendVec_binderize/4k        81955 ns      39116 ns      17895
BM_sendVec_binderize/8k        95316 ns      45710 ns      15350
BM_sendVec_binderize/16k      112751 ns      54417 ns      12679
BM_sendVec_binderize/32k      146642 ns      71339 ns       9901
BM_sendVec_binderize/64k      214796 ns     104665 ns       6495
  • Zaman, gerçek zamanlı olarak ölçülen gidiş-dönüş gecikmesini gösterir.
  • CPU, CPU'ların test için programlandığı toplam süreyi gösterir.
  • Yinelemeler, test fonksiyonunun kaç kez yürütüldüğünü gösterir.

Örneğin, 8 baytlık bir veri yükü için:

BM_sendVec_binderize/8         69974 ns      32700 ns      21296

… ciltleyicinin elde edebileceği maksimum verim şu şekilde hesaplanır:

8 baytlık yük ile MAKS verim = (8 * 21296)/69974 ~= 2,423 b/ns ~= 2,268 Gb/s

Test seçenekleri

Sonuçları .json biçiminde almak için testi --benchmark_format=json bağımsız değişkeniyle çalıştırın:

libhwbinder_benchmark --benchmark_format=json
{
  "context": {
    "date": "2017-05-17 08:32:47",
    "num_cpus": 4,
    "mhz_per_cpu": 19,
    "cpu_scaling_enabled": true,
    "library_build_type": "release"
  },
  "benchmarks": [
    {
      "name": "BM_sendVec_binderize/4",
      "iterations": 32342,
      "real_time": 47809,
      "cpu_time": 21906,
      "time_unit": "ns"
    },
   ….
}

Gecikme testlerini çalıştır

Gecikme testi, istemcinin işlemi başlatmaya başlaması, işlem için sunucu işlemine geçmesi ve sonucu alması için geçen süreyi ölçer. Test ayrıca, öncelikli devralmayı desteklemeyen veya senkronizasyon bayrağını dikkate almayan bir zamanlayıcı gibi işlem gecikmesini olumsuz etkileyebilecek bilinen kötü zamanlayıcı davranışlarını da arar.

  • Bağlayıcı gecikme testi frameworks/native/libs/binder/tests/schd-dbg.cpp konumundadır.
  • Hwbinder gecikme testi system/libhwbinder/vts/performance/Latency.cpp dosyasındadır.

Test sonuçları

Sonuçlar (.json biçiminde), ortalama/en iyi/en kötü gecikmeye ilişkin istatistikleri ve kaçırılan son teslim tarihlerinin sayısını gösterir.

Test seçenekleri

Gecikme testleri aşağıdaki seçenekleri kullanır:

Emretmek Tanım
-i value Yineleme sayısını belirtin.
-pair value Süreç çiftlerinin sayısını belirtin.
-deadline_us 2500 Son teslim tarihini bizde belirtin.
-v Ayrıntılı (hata ayıklama) çıktı alın.
-trace Son teslim tarihine ulaşıldığında izlemeyi durdurun.

Aşağıdaki bölümlerde her seçenek ayrıntılı olarak açıklanmakta, kullanım açıklanmakta ve örnek sonuçlar verilmektedir.

Yinelemeleri belirtin

Çok sayıda yinelemenin ve ayrıntılı çıktının devre dışı bırakıldığı örnek:

libhwbinder_latency -i 5000 -pair 3
{
"cfg":{"pair":3,"iterations":5000,"deadline_us":2500},
"P0":{"SYNC":"GOOD","S":9352,"I":10000,"R":0.9352,
  "other_ms":{ "avg":0.2 , "wst":2.8 , "bst":0.053, "miss":2, "meetR":0.9996},
  "fifo_ms": { "avg":0.16, "wst":1.5 , "bst":0.067, "miss":0, "meetR":1}
},
"P1":{"SYNC":"GOOD","S":9334,"I":10000,"R":0.9334,
  "other_ms":{ "avg":0.19, "wst":2.9 , "bst":0.055, "miss":2, "meetR":0.9996},
  "fifo_ms": { "avg":0.16, "wst":3.1 , "bst":0.066, "miss":1, "meetR":0.9998}
},
"P2":{"SYNC":"GOOD","S":9369,"I":10000,"R":0.9369,
  "other_ms":{ "avg":0.19, "wst":4.8 , "bst":0.055, "miss":6, "meetR":0.9988},
  "fifo_ms": { "avg":0.15, "wst":1.8 , "bst":0.067, "miss":0, "meetR":1}
},
"inheritance": "PASS"
}

Bu test sonuçları aşağıdakileri gösterir:

"pair":3
Bir istemci ve sunucu çifti oluşturur.
"iterations": 5000
5000 yineleme içerir.
"deadline_us":2500
Son tarih 2500us'tur (2,5ms); çoğu işlemin bu değeri karşılaması bekleniyor.
"I": 10000
Tek bir test yinelemesi iki (2) işlemi içerir:
  • Normal önceliğe göre bir işlem ( CFS other )
  • Gerçek zamanlı önceliğe göre tek işlem ( RT-fifo )
5000 yineleme toplam 10000 işleme eşittir.
"S": 9352
İşlemlerin 9352'si aynı CPU'da senkronize ediliyor.
"R": 0.9352
İstemci ve sunucunun aynı CPU'da birlikte senkronize edilme oranını gösterir.
"other_ms":{ "avg":0.2 , "wst":2.8 , "bst":0.053, "miss":2, "meetR":0.9996}
Normal öncelikli arayan tarafından verilen tüm işlemler için ortalama ( avg ), en kötü ( wst ) ve en iyi ( bst ) durum. İki işlem son tarihi miss ve karşılama oranı ( meetR ) 0,9996 oluyor.
"fifo_ms": { "avg":0.16, "wst":1.5 , "bst":0.067, "miss":0, "meetR":1}
other_ms benzer, ancak istemci tarafından rt_fifo önceliğine sahip işlemler için kullanılır. fifo_ms other_ms daha iyi bir sonuca sahip olması muhtemeldir (ancak gerekli değildir), daha düşük avg ve wst değerleri ve daha yüksek bir meetR ile (arka planda yük olduğunda fark daha da önemli olabilir).

Not: Arka plan yükü, gecikme testindeki aktarım sonucunu ve other_ms tuple'ını etkileyebilir. Arka plan yükünün RT-fifo daha düşük önceliğe sahip olması koşuluyla yalnızca fifo_ms benzer sonuçlar gösterebilir.

Çift değerlerini belirtin

Her istemci işlemi, istemciye ayrılmış bir sunucu işlemiyle eşleştirilir ve her çift, bağımsız olarak herhangi bir CPU'ya programlanabilir. Ancak, SYNC bayrağı honor olduğu sürece bir işlem sırasında CPU geçişi gerçekleşmemelidir.

Sistemin aşırı yüklenmediğinden emin olun! Aşırı yüklenmiş bir sistemde yüksek gecikme beklenirken, aşırı yüklenmiş bir sistem için test sonuçları yararlı bilgiler sağlamaz. Daha yüksek basınçla bir sistemi test etmek için -pair #cpu-1 (veya -pair #cpu dikkatli bir şekilde) kullanın. -pair n kullanarak n > #cpu kullanarak test yapmak sistemi aşırı yükler ve gereksiz bilgiler üretir.

Son tarih değerlerini belirtin

Kapsamlı kullanıcı senaryosu testlerinden sonra (gecikme testini nitelikli bir ürün üzerinde çalıştırarak), karşılanması gereken son tarihin 2,5 ms olduğunu belirledik. Daha yüksek gereksinimleri olan (1000 fotoğraf/saniye gibi) yeni uygulamalar için bu son tarih değeri değişecektir.

Ayrıntılı çıktıyı belirtin

-v seçeneğinin kullanılması ayrıntılı çıktıyı görüntüler. Örnek:

libhwbinder_latency -i 1 -v

-------------------------------------------------- service pid: 8674 tid: 8674 cpu: 1 SCHED_OTHER 0
-------------------------------------------------- main pid: 8673 tid: 8673 cpu: 1 -------------------------------------------------- client pid: 8677 tid: 8677 cpu: 0 SCHED_OTHER 0
-------------------------------------------------- fifo-caller pid: 8677 tid: 8678 cpu: 0 SCHED_FIFO 99 -------------------------------------------------- hwbinder pid: 8674 tid: 8676 cpu: 0 ??? 99
-------------------------------------------------- other-caller pid: 8677 tid: 8677 cpu: 0 SCHED_OTHER 0 -------------------------------------------------- hwbinder pid: 8674 tid: 8676 cpu: 0 SCHED_OTHER 0
  • Hizmet iş parçacığı SCHED_OTHER önceliğiyle oluşturulur ve CPU:1 pid 8674 ile çalıştırılır.
  • Daha sonra ilk işlem fifo-caller tarafından başlatılır. Bu işleme hizmet vermek için hwbinder, sunucunun önceliğini ( pid: 8674 tid: 8676 ) 99'a yükseltir ve ayrıca bunu geçici bir planlama sınıfıyla ( ??? olarak yazdırılır) işaretler. Zamanlayıcı daha sonra sunucu işlemini çalıştırmak için CPU:0 koyar ve istemcisiyle aynı CPU ile senkronize eder.
  • İkinci işlem arayan kişinin SCHED_OTHER önceliği var. Sunucu kendi sürümünü düşürür ve arayana SCHED_OTHER önceliğiyle hizmet verir.

Hata ayıklama için izlemeyi kullan

Gecikme sorunlarının hatalarını ayıklamak için -trace seçeneğini belirtebilirsiniz. Gecikme testi kullanıldığında, kötü gecikme tespit edildiği anda tracelog kaydını durdurur. Örnek:

atrace --async_start -b 8000 -c sched idle workq binder_driver sync freq
libhwbinder_latency -deadline_us 50000 -trace -i 50000 -pair 3
deadline triggered: halt ∓ stop trace
log:/sys/kernel/debug/tracing/trace

Aşağıdaki bileşenler gecikmeyi etkileyebilir:

  • Android oluşturma modu . Eng modu genellikle kullanıcı hata ayıklama modundan daha yavaştır.
  • Çerçeve . Çerçeve hizmeti, ciltleyiciyi yapılandırmak için ioctl nasıl kullanır?
  • Bağlayıcı sürücüsü . Sürücü ince taneli kilitlemeyi destekliyor mu? Performansı değiştiren tüm yamaları içeriyor mu?
  • Çekirdek sürümü . Çekirdeğin gerçek zamanlı yeteneği ne kadar iyi olursa, sonuçlar da o kadar iyi olur.
  • Çekirdek yapılandırması Çekirdek yapılandırması DEBUG_PREEMPT ve DEBUG_SPIN_LOCK gibi DEBUG yapılandırmalarını içeriyor mu?
  • Çekirdek zamanlayıcı . Çekirdeğin Enerji Duyarlı bir zamanlayıcısı (EAS) veya Heterojen Çoklu İşleme (HMP) zamanlayıcısı var mı? Herhangi bir çekirdek sürücüsü ( cpu-freq sürücüsü, cpu-idle sürücüsü, cpu-hotplug vb.) zamanlayıcıyı etkiler mi?