Aus Linux-Magazin 02/2019

Performance messen mit dem Kerneltool Perf

© bowie15, 123RF

Über das Linux-Subsystem Performance Counters erlaubt der Kernel Performance-Analysen mit Bordmitteln. Perf ist leicht zu bedienen und genießt wegen der Innenperspektive gegenüber anderen Tools Vorteile.

Systeme schneller zu machen, das gehört zum Kerngeschäft der IT. Dessen Betreiber wollen in der Regel Ressourcen in Rechenzentren optimieren, Energie, Platz und Kosten sparen, den Start von Entertainmentsystemen im Wohnzimmer oder Auto beschleunigen oder, in der Wissenschaft, Algorithmen eleganter implementieren.

Bei komplexen Systemen mit vielen Komponenten ergeben sich Performance-Probleme meist aus unterschiedlichen Ursachen. Hardware-seitig tragen wahlweise die CPU, der Arbeitsspeicher, die Busauslastung, das Speichersystem (Block-I/O) oder das Netzwerk dazu bei. Software-seitig erzeugen das Betriebssystem, die Ausführungsumgebung der Programmiersprache, Bibliotheken oder die entsprechende Anwendung Engpässe. Die Sache erschwert, dass diese Komponenten sich häufig noch gegenseitig beeinflussen. Obwohl die Systeme für sich genommen problemlos arbeiten, führt die Interaktion zu Reibungen.

Den Fehler im Zusammenspiel all dieser Komponenten zu erkennen, verlangt vom Beobachter einerseits eine Vogelperspektive einzunehmen, andererseits aber auch über detailliertes Wissen zu allen beteiligten Bereichen zu verfügen. Nicht viele IT-Profis vereinen diese Fähigkeiten, was Performance-Optimierung zu einer spannenden, aber auch anspruchsvollen Tätigkeit macht.

Zum Glück existieren auch hier, wie für viele IT-Bereiche, eine Menge Werkzeuge, die sich auf solche Aufgaben spezialisieren. Typische Beispiele sind die bekannten Ps, Stat, Top, Htop, Oprofile [1], Systemtap [2] und so weiter.

Auftritt: Perf

Das im Artikel vorgestellte Werkzeug Perf [3] ist hingegen seit Version 2.6.31 direkt in den Kernel integriert, verwendet dessen Performance-Counters-Subsystem und beherrscht sowohl Profiling als auch Tracing.

Beim Profiling wertet Perf Daten der Hardware-Register aus, die bestimmte Hardware-Events zählen. So erzeugt es zu bestimmten Zeitpunkten Statistiken, um einen Eindruck vom System zu gewinnen. Die Genauigkeit hängt dabei von der Messhäufigkeit ab.

Beim Tracing hingegen protokolliert Perf über Tracepoints bestimmte Ereignisse. Zu diesen zählen Software-Events, etwa Kontextwechsel, aber auch Hardware-Events, zum Beispiel ausgeführte Instruktionen, Cache-Anfragen und so weiter. Im weitesten Sinne gehören auch die Systemmeldungen dazu.

Admins und Entwickler sollten dabei beachten, dass Tracing das System sehr stark beeinflussen kann. Beispielsweise läuft »dd« unter Strace deutlich langsamer als ohne. Generell müssen sie berücksichtigen, dass ihre Messungen die Messergebnisse beeinflussen können.

Installation

Das Programm »perf« ist Teil des Linux-Kernels und steckt im Verzeichnis »tools/perf«. Es lässt sich – wie die Ausgabe von »make tools/help« zeigt – mit »make -C perf_install« installieren. Der Anwender kann aber auch einfach in das Verzeichnis »/usr/src/«Linux-Version»/tools/perf« wechseln und dort »make« ausführen.

Weil bestimmte Perf-Funktionen vom Linux-ABI abhängen, liefern die Distributionen oft ein Paket pro Kernelversion aus. Unter Ubuntu 18.10 installiert das Paket »linux-tools-generic« stets die passende Perf-Version.

Hofft der Admin auf aussagekräftige Ausgaben, muss er im Vorfeld – wie beim Debugger – auch die Debug-Symbole für die zu untersuchenden Programme installieren. Diese stecken meist in separaten Archiven. Die automatisch generierten Pakete tragen unter Debian und Ubuntu 18.10 die Endung »-dbgsym«, die manuell erzeugten die Endung »-dbg«.

Workflow

Perf kennt mehr als zwei Dutzend Subkommandos. Eine Übersicht liefert die Eingabe des Befehls ohne Parameter oder [4]. Wer Perf verwendet, startet in der Regel mit »perf list«. Das zeigt die verfügbaren Ereignisse an (Listing 1), die der Anwender dann mit »perf stat« zählt. Der Befehl »record« schreibt Daten auf die Festplatte, »report« zeigt diese zum Durchsuchen an. Mit »script« lassen sich die Daten am Ende weiter auswerten.

Listing 1

Ausgabe von Hardware-Ereignissen (Auszug)

01 $ sudo perf list hardware
02
03 List of pre-defined events (to be used in -e):
04
05   branch-instructions OR branches                    [Hardware event]
06   branch-misses                                      [Hardware event]
07   bus-cycles                                         [Hardware event]
08   cache-misses                                       [Hardware event]
09   [...]

Ereignisse

Wie Listing 1 auch zeigt, gibt der Admin »perf list« auf Wunsch ein optionales Argument mit auf den Weg. Das darf der Typ des Events sein, zum Beispiel »hw« oder »tracepoint«, oder ein regulärer Ausdruck wie in Listing 2.

Listing 2

Ereignissen auf Blockebene (Auszug)

01 $ sudo perf list 'block:*'
02
03 List of pre-defined events (to be used in -e):
04
05   block:block_bio_backmerge                          [Tracepoint event]
06   block:block_bio_bounce                             [Tracepoint event]
07   block:block_bio_complete                           [Tracepoint event]
08   block:block_bio_frontmerge                         [Tracepoint event]
09   block:block_bio_queue                              [Tracepoint event]
10 [...]

Jedes Zeilenende enthält den Typ des Ereignisses in eckigen Klammern. Zudem muss der Admin meistens in den Quelltext schauen, um die genaue Bedeutung des Ereignisses zu erkennen. Den meisten Perf-Kommandos gibt er dann über den Schalter »–events« oder »-e« die zu berücksichtigenden Ereignisse mit.

Top auf Steroiden

Ein paar Beispiele. Zunächst lässt sich mit »perf top« ein Performance-Counter-Profil in Echtzeit erzeugen (Abbildung 1). Die Übersicht gleicht der von Top, allerdings kann der Nutzer hier direkt in die einzelnen Events springen.

Abbildung 1: Der Konsolenbrowser von »perf top --sort=comm,dso« auf einem Intel-Kabylake-System mit Ubuntu 18.10 und Gnome 3.30.1.

Abbildung 1: Der Konsolenbrowser von »perf top –sort=comm,dso« auf einem Intel-Kabylake-System mit Ubuntu 18.10 und Gnome 3.30.1.

»perf stat« zählt die Ereignisse des Gesamtsystems, bis der Anwender es mit [Strg]+[C] abbricht oder der angegebene Befehl sich beendet. Listing 3 zeigt das Subkommando in Aktion, das zwei Ereignisse zum Befehl »factor« auflistet.

Listing 3

Ausgabe von perf stat

01 $ sudo perf stat -e branches -e branch-misses factor 120808125801214124898080833
02 120808125801214124898080833: 13 29 911 7589 21089 77471 28369829
03
04  Performance counter stats for 'factor 120808125801214124898080833':
05
06        191.242  branches
07             10.332  branch-misses           #    5,40% of all branches
08
09        0,000649438 seconds time elapsed
10
11        0,000699000 seconds user
12        0,000000000 seconds sys

Daten-Rekorder

Der Perf-Befehl »record« kann ein Performance-Counter-Profil für ein bestimmtes Kommando generieren. Will sich der Anwender einen Überblick über das Gesamtsystem verschaffen oder ist der zu untersuchende Prozess unbekannt, spannt er einfach den Befehl »sleep« vor den Karren:

sudo perf record -ag sleep 5

Diese Zeile erzeugt die Standarddatei »perf.data« im aktuellen Verzeichnis. Der Schalter »-a« sorgt dafür, dass Perf alle CPUs berücksichtigt, und »-g« generiert einen Call Graph. Über »-i« lässt sich »perf record« mit einer Datei füttern.

Das Kommando »perf report« wertet die gespeicherten Daten aus und nutzt dafür die Datei »perf.data«. Wie bei »perf top« präsentiert der Befehl eine Übersicht. Über einen Druck auf [Eingabe] erhält der Nutzer zudem die Details zu den jeweiligen Funktionen.

Abbildung 2: Perf misst die Performance des Standardbrowser mit »perf report --sort=comm,dso«.

Abbildung 2: Perf misst die Performance des Standardbrowser mit »perf report –sort=comm,dso«.

Übrigens sorgt der Schalter »–sort= comm,dso« (wie in Abbildung 1) für eine bessere Übersicht. Abbildung 2 zeigt die Ausgabe eines Intel-Kabylake-Systems mit Gnome 3.30.1 beim Abspielen eines Videos in Firefox 63.0.3. Das Bild verdeutlicht, dass beim Dekodieren die CPU und nicht die GPU zum Einsatz kommt.

Event-getrieben

Wenn nur bestimmte Ereignisse interessieren, hilft der Schalter »-e« weiter. Listing 4 zeigt die Ausgabe auf einem System mit laufendem Rsync.

Listing 4

Events verfolgen

01 $ sudo perf report --stdio
02 [...]
03 # Samples: 1K of event 'block:block_rq_issue'
04 # Event count (approx.): 1741
05 #
06 # Children  Self  Command      Shared Object     Symbol
07 # ........  ....  ...........  ................  ....................
08 #
09   93.74%  93.74%  rsync        kernel.kallsyms]  [k] blk_peek_request
10                   |
11                   |--89.20%-- __lxstat64
12                   |           blk_peek_request
13                   |
14                   |--3.45%-- __GI___mkdir
15                   |          blk_peek_request
16                   |
17                 |--0.63%-- 0x646c6975622f3930
18                 |          __GI___link
19                 |          blk_peek_request
20                 |
21                  --0.46%-- 0x6d492f636f642f65
22                            __GI___link
23                            blk_peek_request
24
25   89.20%  0.00% rsync    libc-2.27.so    [.] __lxstat64
26                 |
27                 ---__lxstat64
28                    blk_peek_request
29 [...]

Dank »–stdio« gibt Perf die Übersicht als reinen Text direkt auf der Konsole aus. Das aufgezeichnete Ereignis war dabei eine Anfrage an den Blocklayer des Kernels. Die Befehlszeile lautete:

sudo perf record -e block:block_rq_issue -ag

Doch auch hübsche Grafiken lassen sich mit Perf erzeugen.

On Fire

Flamegraphs gelten zurzeit als letzter Schrei. Dank ihnen ermitteln Admins und Entwickler die am häufigsten verwendeten Pfade einer Software. Auch die in die Browser integrierten Entwicklerwerkzeuge erzeugen mittlerweile solche Grafiken (Abbildung 3).

Abbildung 3: Die Entwicklerwerkzeuge der Browser bringen auch Mittel zur Performance-Analyse mit.

Abbildung 3: Die Entwicklerwerkzeuge der Browser bringen auch Mittel zur Performance-Analyse mit.

Die x-Achse zeigt die Auslastung der einzelnen Prozesse, die y-Achse die Auflösung jedes Funktionsaufrufs. Je breiter die Blöcke, desto mehr Ressourcen beanspruchen deren Prozesse. Das macht deutlich, welche Bereiche problematisch sind und sich zu optimieren lohnen.

Auch aus den Perf-Daten erzeugen Admins Flamegraphs. Die Skripte dafür müssen Anwender nicht selbst schreiben, sie warten teils auf Github [5]:

git clone https://github.com/brendangregg/FlameGraph

Die Befehle aus Listing 5 zeichnen die Performance-Daten auf und erzeugen mit »perf script« einen Flamegraph (Abbildung 4). Der zeigt: Obwohl der Browser ein 720p-Video abspielt, bleibt der Kernel meist im Ruhezustand. Im Browser lassen sich einzelne Abschnitte des Flamegraphen vergrößern und verkleinern.

Abbildung 4: Der per Skript erzeugte Flamegraph aus Perf-Daten: Ihn darf der Anwender auf Wunsch per Mausklick vergrößern und verkleinern.

Abbildung 4: Der per Skript erzeugte Flamegraph aus Perf-Daten: Ihn darf der Anwender auf Wunsch per Mausklick vergrößern und verkleinern.

Listing 5

Befehle zum Erzeugen eines Flamegraph

01 sudo perf record -F 99 -a -g -- sleep 10
02 sudo perf script > out.perf
03 ./stackcollapse-perf.pl out.perf > out.folded
04 ./flamegraph.pl out.folded > out.svg
05 firefox out.svg

Dynamisches Tracing

Über das Perf-Subkommando »probe« und den Schalter »–add« legen Admins nicht zuletzt so genannte sdynamische Tracepoints fest. Listing 6 zeigt das Vorgehen stellvertretend für die Linux-Funktion »tcp_sendmsg()«.

Listing 6

tcp_sendmsg als dynamischer Tracepoint

01 $ sudo perf probe --add='tcp_sendmsg'
02 Added new event:
03   probe:tcp_sendmsg    (on tcp_sendmsg)
04 [...]
05 $ sudo perf record -e probe:tcp_sendmsg -aR sleep 5
06 [ perf record: Woken up 1 times to write data ]
07 $ sudo perf report --stdio
08 [...]

Dynamisches Duo

Das Linux-Subsystem Perf und die Werkzeugsammlung »perf« bieten viele Möglichkeiten, ein System zu analysieren. Ohne große Umstände erheben Admins Daten und werten diese mit den vorhandenen Werkzeugen und Skripten aus, um einen Überblick zu erhalten.

Die richtige Interpretation der Daten erfordert etwas Wissen sowohl über das System als auch über die zahlreichen Möglichkeiten des Framework. Das ist jedoch bei anderen Werkzeugen, etwa Debuggern, nicht anders.

Praktisch ist, dass der Linux-Kernel Perf direkt mitliefert, ohne dass der Nutzer externe Module benötigt. Das stellt nicht nur sicher, dass Perf auch zukünftig Pflege erhält, sondern erlaubt es auch, User- und Kernelspace gleichermaßen abzudecken.

Lesestoff

Obwohl als Suchbegriff eigentlich eher ungeeignet, finden sich zu Perf dennoch schnell zahlreiche Ressourcen im Netz. Allen voran sicherlich die Seiten von Brendan Gregg [6], der bei Sun an Dtrace mitgearbeitet hat und der Perf jetzt bei Netflix als Performance-Engineer intensiv nutzt. Sein Buch “System Performance” [7] gilt in diesem Bereich als eines der Standardwerke.

Auch Admins und Entwickler profitieren davon, die grundlegenden Fähigkeiten von Perf zu kennen, um Probleme schneller zu analysieren. Einige Entwicklungsumgebungen integrieren Perf bereits, es gibt auch ein paar Schulungsanbieter. Klar scheint: Performance-Optimierungen spielen in der Systemadministration auch künftig eine wichtige Rolle. Mit Bpftrace (siehe Kasten “BPF-Trace”, [8]) wartet schon das nächste spannende Projekt in der Pipeline.

BPF-Trace

Anfang Herbst 2018 veröffentlichte Alastair Robertson die Hochsprache BPF-Trace [8], deren Kompilat in der EBPF-VM des Linux-Kernels läuft. Somit kann der Kernel gewisse Operationen, beispielsweise Filterprozesse, direkt im Kernelspace starten. Das spart Kontextwechsel zwischen Kernel- und Userspace, was das System deutlich weniger belastet.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 4 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Nach oben