Eclipse, C, Laufzeitanalyse

Transcription

Eclipse, C, Laufzeitanalyse
Eclipse, C, Laufzeitanalyse
Kurzanleitung von Boris Budweg
v0.2, 03.12.2011
Die folgenden Seiten klären diese Fragen:
•
•
Wo nutzt mein Programm die CPU am meisten? Wo sollte ich nicht optimieren? –
GPROF
2
Welche Wege werden in meinen Programmcode durchlaufen? Versteckt sich "Dead
Code"? – GCOV
4
1
Wo nutzt mein Programm die CPU am meisten? Wo sollte
ich nicht optimieren? – GPROF
Manchmal wird ein Programm (subjektiv gefühlt oder an harten Kriterien gescheitert)
„träge“: Es muß optimiert werden. Jedoch sollte man seine Energie mit Bedacht einsetzen,
denn es gilt – wie fast immer – die 80-20-Regel. In 20% des Codes wird 80% der CPU-Last
erzeugt. Also gilt es, diese 20% auszumachen, und nur diese zu optimieren. Die Optimierung
der anderen 80% wäre vergebene Liebesmühe. Statische Code-Analyse hilft nicht, denn erst
zur Laufzeit wird entschieden, welche Wege der Rechner durch den Code beschreitet. Diese
Informationen liefert uns "GPROF". Es wird von GCC unterstützt, der den Code
„instrumentiert“. Klingt kompliziert, ist aber mit Eclipse und den verfügbaren Plugins sehr
schnell gemacht:
In den Compileroptionen des Programms muß "-pg" übergeben werden:
Ebenso bei den Linkeroptionen:
2
Bauen Sie das Projekt neu und starten Sie ihr Programm wie gewohnt. Lassen Sie es etwas
laufen (um ggf. Initialisierungszeiten zu relativieren), während Sie es (falls nötig und möglich)
dazu treiben, mutmaßliche Zeitfresser auszuführen. Beenden Sie das Programm wieder. Im
Project-Explorer von Eclipse wählen Sie das Verzeichnis, in welchem sich die ausführbare
Datei befindet und drücken "F5" (Refresh, geht auch mit rechter Maustaste).
Eine neue Datei "gmon.out" erscheint:
Öffnen Sie diese, wird ein Baum angezeigt, in dem der Anteil an verbrauchter CPU-Zeit dem
Source zugeordnet wird:
Wie Sie in diesem Beispiel sehen, wird ein Viertel der Laufzeit in einer Funktion verbracht.
Optimierungstechniken sind nicht Gegenstand dieser Kurzanleitung.
Hintergrund „Instrumentierung“:
An entscheidenden Stellen im Programm (z.B. Funktions-Ein- und –Austritt) fügt der
Compiler extra Instruktionen ein (z.B. Zeitstempel speichern). Diese zusätzlichen Ausgaben
werden in einer Datei gespeichert (z.B. gmon.out) und müssen (meist mit KommandozeilenTools, z.B. GPROF) ausgewertet werden (erledigt zum Glück ein Eclipse-Plugin für Sie).
Übrigens: "Assembler ist eine Methode, Programme die zu langsam laufen so
umzuschreiben, dass sie überhaupt nicht mehr laufen" ;-)
3
Welche Wege werden in meinen Programmcode
durchlaufen? Versteckt sich "Dead Code"? – GCOV
Natürlich kann man dies mit Hilfe des Debuggers herausfinden. Das ist jedoch mühsam und
bei großen Projekten nicht zielführend. Einfacher geht es mit GCOV.
Es gelten sämtliche Beschreibungen wie zuvor bei GPROF, nur heißt diesmal das Zauberwort
"-fprofile-arcs –ftest-coverage“:
4
Diesmal es werden zwei Dateien die im Debug-Ordner statt einer im Projektverzeichnis
erzeugt:
Nach einem Doppelklick auf eines der Elemente im gcov-View unten sieht man links von der
Zeilennummer der Sources die Häufigkeit, mit welcher der Prozessor jeweils den
entsprechenden Code ausgeführt hat. Rote Zeilen wurden nie durchlaufen, grüne wurden
durchlaufen, dunkelgrüne besonders häufig.
5
Nicht gefärbten Zeilen wurde bei der Übersetzung des Compilers kein eigener
Maschinencode zugewiesen. So bekommen z.B. auch mehrere Variablen-Deklarationen in C
keine einzige eigene Zeile Assembler, denn der Stackpointer muß sowieso schon bei
Funktionseintritt erhöht werden (siehe Eclipse-View „Registers“, Register „ESP“ bei x86CPUs, sowie Eclipse-View „Assembler“).
Details der Toolkette:
•
Während des Compilierens mit „-pg“ werden *.gcno - Files erstellt. Diese enthalten
Source-Referenzen (später vom Parser des Plugins benötigt)
•
Bei der Ausführung werden *.gcda - Files generiert. Diese enthalten die
Laufzeitauswertung.
•
Das Eclipse-Plugin parst die Ausgaben von "GCOV" und färbt die Zeilen in Eclipse rot
oder grün ein.
•
Die GCOV-Ausgaben kann man sich auch manuell erzeugen, indem man GCOV mit
einem C-File-Namen als Parameter aufruft. Natürlich sollten zu dem C-File die
*.gc??-Files bereits vorhanden sein. Dann wird eine *.gcov - (text-) Datei erstellt, die
den Sourcecode mit Coverage-Informationen enthält.
•
mit dem GCOV-Schalter "-b" erhält man Einblick in jeden möglichen
Entscheidungszweig der Auswertung eines logischen Ausdrucks (Multiple Condition
Decision Coverage -> Software-Test). MCDC-Verletzungen lassen sich mit
type file.gcov | grep "taken 0%"
leicht aus den erzeugten .gcov-Files herausfiltern.
•
Mehr zu GCOV:
http://gcc.gnu.org/onlinedocs/gcc/Gcov.html
•
Mehr zu Softwaretest:
http://homepages.thm.de/~bbdw58/weiterfuehrend/SW_test.pdf
6