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