Android 8.0 umfasst Binder- und Hwbinder-Leistungstests für Durchsatz und Latenz. Es gibt zwar viele Szenarien für die Erkennung wahrnehmbarer Leistung ist die Ausführung solcher Szenarien zeitaufwändig und die Ergebnisse erst nach der Integration eines Systems verfügbar. Bereitgestellte Leistung wird verwendet Tests erleichtern Tests während der Entwicklung und erkennen schwerwiegende Probleme und die User Experience zu verbessern.
Leistungstests umfassen die folgenden vier Kategorien:
- Binder-Durchsatz (verfügbar in
system/libhwbinder/vts/performance/Benchmark_binder.cpp
) - Binder-Latenz (verfügbar in
frameworks/native/libs/binder/tests/schd-dbg.cpp
) - hwbinder-Durchsatz (verfügbar in
system/libhwbinder/vts/performance/Benchmark.cpp
) - Hwbinder-Latenz (verfügbar in
system/libhwbinder/vts/performance/Latency.cpp
)
Über binder und hwbinder
Binder und Hwbinder sind Android Inter-Process Communication (IPC) Infrastrukturen mit demselben Linux-Treiber, aber mit den folgenden qualitative Unterschiede:
Seitenverhältnis | Bindemittel | HWbinder |
---|---|---|
Zweck | Bereitstellung eines allgemeinen IPC-Schemas für das Framework | Mit Hardware kommunizieren |
Attribut | Für die Nutzung des Android-Frameworks optimiert | Minimaler Aufwand mit niedriger Latenz |
Planungsrichtlinie für Vorder-/Hintergrund ändern | Ja | Nein |
Übergebene Argumente | Verwendet die vom Parcel-Objekt unterstützte Serialisierung | Nutzt Streuzwischenspeicher und vermeidet den Aufwand beim Kopieren von Daten, die für Paketserialisierung |
Prioritätsübernahme | Nein | Ja |
Binder- und Hwbinder-Prozesse
Ein Systrace-Visualizer zeigt Transaktionen so an:
Im obigen Beispiel gilt Folgendes:
- Die vier (4) schd-dbg-Prozesse sind Clientprozesse.
- Die vier (4) Binderprozesse sind Serverprozesse (der Name beginnt mit Binder und endet mit einer Sequenznummer.
- Ein Clientprozess ist immer mit einem Serverprozess gekoppelt, der dem an die Kundschaft.
- Alle Client-Server-Prozesspaare werden vom Kernel unabhängig geplant .
In CPU 1 führt der Kernel des Betriebssystems den Client aus, um die Anfrage zu senden. Dann verwendet, wenn möglich, dieselbe CPU, um einen Serverprozess zu aktivieren, und der Kontext wechselt nach Abschluss der Anfrage wieder zurück.
Durchsatz und Latenz
In einer perfekten Transaktion, bei der der Client- und Serverprozess bei nahtlosem Wechsel zwischen Durchsatz- und Latenztests Nachrichten. Wenn der Kernel des Betriebssystems jedoch eine Interrupt-Anfrage (IRQ) verarbeitet, z. B. Hardware, auf Schlösser warten oder einfach festlegen, dass Nachrichten nicht verarbeitet werden sollen. kann sich eine Latenzblase bilden.
Der Durchsatztest generiert eine große Anzahl von Transaktionen mit unterschiedlichen eine gute Schätzung für die reguläre Transaktionszeit (in Best-Case-Szenarien) und den maximalen Durchsatz, den der Binder erreichen kann.
Im Gegensatz dazu führt der Latenztest keine Aktionen für die Nutzlast aus, um der regulären Transaktionszeit. Wir können die Transaktionszeit verwenden, um den Binder zu schätzen. für den schlimmsten Fall Statistiken erstellen und das Verhältnis Transaktionen, deren Latenz eine bestimmte Frist einhält.
Prioritätsumkehrungen verarbeiten
Eine Prioritätsumkehr tritt auf, wenn ein Thread mit höherer Priorität Es wird auf einen Thread mit niedrigerer Priorität gewartet. Echtzeitanwendungen haben eine Prioritätsumkehrproblem:
Bei der CFS-Planung (Linux Completely Fair Scheduler) wird immer ein Thread ausgeführt werden kann, auch wenn andere Threads eine höhere Priorität haben. Daher Anwendungen mit CFS-Planung handhaben die Prioritätsumkehr wie erwartet und nicht als Problem. In Fällen, in denen das Android-Framework Echtzeit-Planung benötigt um die Berechtigung von Threads mit hoher Priorität zu gewährleisten. gelöst werden muss.
Beispiel für die Prioritätsumkehr während einer Binder-Transaktion (RT-Thread ist von anderen CFS-Threads logisch blockiert, wenn ein Binder-Thread Dienst):
Um Blockierungen zu vermeiden, können Sie mit der priorisierten Übernahme vorübergehend den Fall eskalieren. den Binder-Thread an einen RT-Thread, wenn er eine Anfrage von einem RT-Client verarbeitet. Denken Sie daran, dass die Echtzeit-Planung nur über begrenzte Ressourcen verfügt und daher verwendet werden sollte. vorsichtig zu sein. In einem System mit n CPUs ist die maximale Anzahl der aktuellen RTF-Systeme Threads ist auch n. müssen zusätzliche RT-Threads möglicherweise warten (und Fristen verpassen), wenn alle CPUs von anderen RT-Threads beansprucht werden.
Um alle möglichen Prioritätsumkehrungen zu beheben, können Sie die Priorität sowohl für binder als auch für hwbinder. Da Binde jedoch weit verbreitet ist, im gesamten System haben, kann das Aktivieren der Prioritätsübernahme für Binder-Transaktionen Das System wird mit mehr RT-Threads gespammt, als es verarbeiten kann.
Durchsatztests ausführen
Der Durchsatztest wird anhand des binder/hwbinder-Transaktionsdurchsatzes durchgeführt. In System ist nicht überlastet, Latenzblasen sind selten und ihre Auswirkungen eliminiert werden, solange die Anzahl der Iterationen hoch genug ist.
- Der binder-Durchsatztest befindet sich in
system/libhwbinder/vts/performance/Benchmark_binder.cpp
- Der hwbinder-Durchsatztest befindet sich in
system/libhwbinder/vts/performance/Benchmark.cpp
Testergebnisse
Beispiel für Ergebnisse von Durchsatztests für Transaktionen mit anderer Nutzlast Größen:
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
- Zeit gibt die in Echtzeit gemessene Umlaufzeit an.
- CPU gibt die akkumulierte Zeit an, wenn CPUs geplant werden. für den Test.
- Iterationen gibt an, wie oft die Testfunktion ausgeführt haben.
Für eine 8-Byte-Nutzlast gilt beispielsweise Folgendes:
BM_sendVec_binderize/8 69974 ns 32700 ns 21296
...der maximale Durchsatz, den der Binder erreichen kann, wie folgt berechnet wird:
MAX-Durchsatz mit 8-Byte-Nutzlast = (8 * 21296)/69974 ~= 2,423 b/ns ~= 2,268 Gbit/s
Testoptionen
Um Ergebnisse im JSON-Format zu erhalten, führen Sie den Test mit der
Argument --benchmark_format=json
:
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"
},
….
}
Latenztests ausführen
Der Latenztest misst die Zeit, die der Client benötigt, um zu beginnen Initialisierung der Transaktion, Wechsel zum Serverprozess für die Verarbeitung und das Ergebnis erhalten. Außerdem wird nach bekannten fehlerhaften Planerverhaltensweisen gesucht, sich negativ auf die Transaktionslatenz auswirken kann, z. B. durch einen Planer, der keine Prioritätsübernahme unterstützen oder das Synchronisierungs-Flag berücksichtigen.
- Der Binder-Latenztest ist in
frameworks/native/libs/binder/tests/schd-dbg.cpp
- Der hwbinder-Latenztest läuft
system/libhwbinder/vts/performance/Latency.cpp
Testergebnisse
Die Ergebnisse (im JSON-Format) enthalten Statistiken für die durchschnittliche/beste/schlechteste Latenz sowie den die Anzahl der verpassten Fristen.
Testoptionen
Latenztests haben folgende Optionen:
Befehl | Beschreibung |
---|---|
-i value |
Geben Sie die Anzahl der Iterationen an. |
-pair value |
Geben Sie die Anzahl der Prozesspaare an. |
-deadline_us 2500 |
Gib die Frist in uns an. |
-v |
Ausführliche Ausgabe (Debuggen) |
-trace |
Stoppt den Trace bei einem Deadline-Treffer. |
In den folgenden Abschnitten werden die einzelnen Optionen beschrieben, die Nutzung beschrieben und Beispielergebnisse.
Iterationen angeben
Beispiel mit einer großen Anzahl von Iterationen und deaktivierter ausführlicher Ausgabe:
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"
}
Diese Testergebnisse zeigen Folgendes:
"pair":3
- Erstellt ein Client-Server-Paar.
"iterations": 5000
- Umfasst 5.000 Iterationen.
"deadline_us":2500
- Die Frist beträgt 2.500 Sekunden (2,5 ms); bei den meisten Transaktionen diese Wert.
"I": 10000
- Ein Testdurchlauf umfasst zwei (2) Transaktionen:
<ph type="x-smartling-placeholder">
- </ph>
- Eine Transaktion mit normaler Priorität (
CFS other
) - Eine Transaktion nach Echtzeitpriorität (
RT-fifo
)
- Eine Transaktion mit normaler Priorität (
"S": 9352
- 9.352 der Transaktionen werden in derselben CPU synchronisiert.
"R": 0.9352
- Gibt das Verhältnis an, mit dem Client und Server in dieselbe CPU.
"other_ms":{ "avg":0.2 , "wst":2.8 , "bst":0.053, "miss":2, "meetR":0.9996}
- Der Durchschnitt (
avg
), die schlechtesten (wst
) und die besten (bst
)-Fall für alle Transaktionen, die von einem Aufrufer mit normaler Priorität ausgeführt werden. Zwei Transaktionenmiss
die Frist, wodurch die Erfüllungsrate erreicht wird (meetR
) 0,9996. "fifo_ms": { "avg":0.16, "wst":1.5 , "bst":0.067, "miss":0, "meetR":1}
- Ähnlich wie
other_ms
, aber für Transaktionen, die von einem Kunden mit Prioritätrt_fifo
. Es ist wahrscheinlich (aber nicht erforderlich),fifo_ms
hat ein besseres Ergebnis alsother_ms
mit niedrigeren Werten Werte füravg
undwst
sowie einen höheren Wert fürmeetR
Bei einer Auslastung im Hintergrund kann der Unterschied sogar noch größer sein.
Hinweis:Die Hintergrundlast kann sich auf den Durchsatz auswirken.
und dem Tupel other_ms
im Latenztest. Nur die
fifo_ms
zeigt möglicherweise ähnliche Ergebnisse an, solange die Hintergrundlast
eine niedrigere Priorität als RT-fifo
hat.
Paarwerte angeben
Jeder Clientprozess ist mit einem Serverprozess verbunden, der speziell für den Client vorgesehen ist.
Jedes Paar kann für jede CPU
unabhängig geplant werden. Die CPU
Die Migration sollte nicht während einer Transaktion stattfinden, solange das SYNC-Flag
honor
Das System darf nicht überlastet sein. Während hohe Latenz bei einer Überlastung
erwartet wird, liefern Testergebnisse für ein überlastetes System keine nützlichen
Informationen. Wenn du ein System mit höherem Druck testen möchtest, verwende -pair
#cpu-1
(oder -pair #cpu
mit Vorsicht). Testen mit
-pair n
mit n > #cpu
überlädt das
und generiert nutzlose Informationen.
Werte für Frist angeben
Nach umfassenden Tests von Nutzerszenarien (durch Ausführen des Latenztests qualifiziert ist, haben wir eine Frist von 2,5 ms als Frist festgelegt. Für neue Anwendungen mit höheren Anforderungen (z. B. 1.000 Fotos/Sekunde) ändert sich der Wert für die Frist.
Ausführliche Ausgabe angeben
Mit der Option -v
wird eine ausführliche Ausgabe angezeigt. Beispiel:
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
- Der Dienstthread wird mit einem
SCHED_OTHER
und führen sie inCPU:1
mitpid 8674
aus. - Die erste Transaktion wird dann durch einen
fifo-caller
Für diese Transaktion aktualisiert der Hwbinder das Priorität des Servers (pid: 8674 tid: 8676
) auf 99 gesetzt. mit einer vorübergehenden Planungsklasse (ausgedruckt als???
). Der Planer führt den Serverprozess inCPU:0
aus und synchronisiert ihn mit dem dieselbe CPU mit seinem Client. - Der Aufrufer der zweiten Transaktion hat eine
Priorität
SCHED_OTHER
. Der Server führt ein Downgrade selbst aus und Anrufer mit PrioritätSCHED_OTHER
.
Trace zur Fehlerbehebung verwenden
Sie können die Option -trace
angeben, um Latenzprobleme zu beheben. Wann?
stoppt der Latenztest die Tracelog-Aufzeichnung in dem Moment, in dem ein Fehler
Latenz erkannt. Beispiel:
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
Die folgenden Komponenten können die Latenz beeinflussen:
- Android-Build-Modus Der Entwicklungsmodus ist in der Regel langsamer als Debug-Modus.
- Framework. Wie nutzt der Framework-Dienst
ioctl
für die Konfiguration für den Binder? - Binder-Treiber: Unterstützt der Treiber detaillierte Sperren? Enthält es alle Patches zur Leistungsumwandlung?
- Kernel-Version Je besser der Kernel in Echtzeit ist, desto besser sind die Ergebnisse.
- Kernel-Konfiguration Enthält die Kernel-Konfiguration
DEBUG
-Konfigurationen wieDEBUG_PREEMPT
undDEBUG_SPIN_LOCK
? - Kernel-Planer Hat der Kernel einen energiebewussten
Planer (EAS) oder Heterogenes Multi-Processing-(HMP)-Planer? Kernel ausführen
Fahrer (
cpu-freq
Fahrer,cpu-idle
Fahrer,cpu-hotplug
usw.) sich auf den Planer auswirken?