C++-Profiling unter Linux: Ein Leitfaden für alle, die Code beschleunigen wollen

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Ihr C++-Code läuft langsam? Zeit, unter die Haube zu schauen

\n\n

Sie haben einen auf den ersten Blick perfekten C++-Code geschrieben. Die Kompilierung war fehlerfrei, das Programm startet... aber es läuft irgendwie träge. Kommt Ihnen bekannt vor? Die Hand zuckt, alles in Assembler umzuschreiben oder schnell Multithreading hinzuzufügen. Keine Eile. Höchstwahrscheinlich liegt das Problem nicht in der Architektur, sondern in ein paar „heißen“ Funktionen, die 90% der CPU-Zeit verschlingen.

\n\n

In der Linux-Welt haben wir ein mächtiges Arsenal an Werkzeugen für das Profiling von C++-Code. Das ist keine Magie, das ist Wissenschaft. Wir raten nicht, wir messen. In diesem Leitfaden zeige ich Ihnen vier praktische Ansätze: vom schnellen „Blick von oben“ bis zum Mikro-Benchmarking. Sie erfahren, wie Sie C++ unter Linux wie ein Profi profilieren.

\n\n

Warum Vermutungen böse sind und Profiling gut

\n\n

Bevor wir in den Code eintauchen, merken Sie sich die goldene Regel der Optimierung: „Optimiere nicht, was nicht gemessen wurde“. Ihre Intuition ist ein schlechter Ratgeber. Oft verbringen wir Stunden mit der Optimierung einer Funktion, die einmal pro Minute aufgerufen wird, und ignorieren eine banale Schleife mit 10 Millionen Iterationen.

\n\n

Profiling gibt Antworten auf drei Hauptfragen:

\n
    \n
  • Wo verbringt das Programm die meiste Zeit?
  • \n
  • Warum passiert das (ineffizienter Algorithmus, viele E/A-Operationen, Cache-Fehltritte)?
  • \n
  • Was hat sich nach Ihren Änderungen geändert?
  • \n
\n\n

Heute besprechen wir vier Werkzeuge, die 99% Ihrer Aufgaben abdecken. Los geht's!

\n\n

Werkzeug Nr. 1: gprof – der Klassiker

\n\n

gprof ist der gute, alte, integrierte GNU-Profiler. Er arbeitet in zwei Schritten: Datensammlung während der Programmausführung und deren Analyse. Vorteile: Sie müssen nichts Zusätzliches installieren, es ist in jeder Distribution enthalten. Nachteile: Es liefert ungefähre Ergebnisse und funktioniert nicht von Haus aus mit Multithread-Programmen.

\n\n

So verwenden Sie gprof

\n\n

Schritt 1. Kompilieren Sie das Programm mit dem speziellen Flag -pg:

\n
g++ -pg -O2 my_program.cpp -o my_program
\n\n

Beachten Sie: Wir verwenden -O2. Einen Debug-Build ohne Optimierungen zu profilieren, ist sinnlos – Sie erhalten ein verzerrtes Bild.

\n\n

Schritt 2. Starten Sie das Programm. Es wird etwas langsamer laufen, da gprof Daten sammelt.

\n
./my_program
\n\n

Schritt 3. Im aktuellen Ordner erscheint eine Datei gmon.out. Analysieren Sie sie:

\n
gprof my_program gmon.out > analysis.txt
\n\n

Öffnen Sie analysis.txt und sehen Sie etwas wie:

\n
Flat profile:\nEach sample counts as 0.01 seconds.\n  %   cumulative   self              self     total\n time   seconds   seconds    calls  us/call  us/call  name\n 60.00      0.06     0.06    10000     6.00     6.00  slow_function\n 20.00      0.08     0.02     5000     4.00     4.00  fast_function\n 10.00      0.09     0.01                             main
\n\n

Voilà! Wir sehen, dass slow_function 60% der Zeit belegt hat. Das ist unser Kandidat für die Optimierung.

\n\n

Beispielcode für das Profiling

\n\n

Schreiben wir ein einfaches Programm, das wir mit allen Werkzeugen profilieren werden:

\n\n
#include <iostream>\n#include <cmath>\n\nvoid slow_function(int n) {\n    volatile double sum = 0.0; // volatile, damit der Compiler nicht auf Null optimiert\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < 1000; ++j) {\n            sum += std::sin(i) * std::cos(j);\n        }\n    }\n    std::cout << sum << std::endl;\n}\n\nvoid fast_function(int n) {\n    volatile int count = 0;\n    for (int i = 0; i < n; ++i) {\n        count += i % 2;\n    }\n    std::cout << count << std::endl;\n}\n\nint main() {\n    slow_function(10000);\n    fast_function(50000);\n    return 0;\n}
\n\n

Kompilieren Sie mit dem Flag -pg und starten Sie

Blogs

Buchempfehlungen