analyze routineerhält man drei Tabellen, die wir uns an unserem Beispielprogramm LINALG in der Version 2.1 und der Optimierungsstufe -O2 ansehen wollen:
Routine Performance Analysis | . | |||||||||||||
(sorted by CPU time (less children)) | . | |||||||||||||
CPU Time | . | CPU Time | Times | . | Routine | |||||||||
(less children) | . | (plus children) | Called | . | Name | |||||||||
0 | . | 627 | 57 | . | 7% | 0 | . | 627 | 57 | . | 7% | 1 | gaussj | |
0 | . | 188 | 17 | . | 3% | 0 | . | 188 | 17 | . | 3% | 2 | testmt | |
0 | . | 127 | 11 | . | 7% | 0 | . | 127 | 11 | . | 7% | 101 | lubksb | |
0 | . | 071 | 6 | . | 5% | 0 | . | 071 | 6 | . | 5% | 1 | ludcmp | |
0 | . | 038 | 3 | . | 5% | 0 | . | 038 | 3 | . | 5% | 10100 | drand_$n | |
0 | . | 029 | 2 | . | 6% | 0 | . | 066 | 6 | . | 1% | 1 | getmat | |
. | . | . | . | . | . | |||||||||
. | . | . | . | . | . | |||||||||
. | . | . | . | . | . |
Routine Performance Analysis | . | . | ||||||||||||||||
(sorted by CPU time (less children)) | . | . | ||||||||||||||||
CPU Time | CPU Time | . | . | |||||||||||||||
(less children) | (plus children) | . | . | |||||||||||||||
. | . | |||||||||||||||||
Min. | Max. | . | Avg. | . | Min. | . | Max. | . | Avg. | . | Routine name | |||||||
0 | . | 627 | 0 | . | 627 | 0 | . | 627 | 0 | . | 627 | 0 | . | 627 | 0 | . | 627 | gaussj |
0 | . | 092 | 0 | . | 096 | 0 | . | 094 | 0 | . | 092 | 0 | . | 096 | 0 | . | 094 | testmt |
0 | . | 813m | 1 | . | 830m | 1 | . | 259m | 0 | . | 813m | 1 | . | 830m | 1 | . | 259m | lubksb |
0 | . | 071 | 0 | . | 071 | 0 | . | 071 | 0 | . | 071 | 0 | . | 071 | 0 | . | 071 | ludcmp |
0 | . | 003m | 0 | . | 021m | 0 | . | 003m | 0 | . | 003m | 0 | . | 021m | 0 | . | 003m | drand_$n |
0 | . | 029 | 0 | . | 029 | 0 | . | 029 | 0 | . | 066 | 0 | . | 066 | 0 | . | 066 | getmat |
. | . | . | . | . | . | |||||||||||||
. | . | . | . | . | . |
Dynamic Call Graph (in topological order, cycles severed) . . f_exit: parents: (spontaneous call) children: fclose[3] for$clos2[3] for$clos2: parents: f_exit children: free[3] t_runc[2] . . MAIN_: parents: main children: for$do_lio[2] for$s_wsle[1] ernorm[1] testmt[1] gaussj[1] setvec[1] setmat[1] getvec[1] getmat[1] getmat: parents: MAIN_ children: drand_$n[10000] getvec: parents: MAIN_ children: drand_$n[100] drand_$n: parents: getvec getmat . .Nach einer Liste aller Routinen, die zum Profilen vorbereitet waren, aber nicht aufgerufen wurden (vor allem eine Menge von Bibliotheksfunktionen) folgt der ``dynamische Aufruf-Graph''. Ein Aufruf-Graph (``Call Graph'') ist eigentlich eine Graphik, die in Baumform darstellt, welche Routine von welcher aufgerufen wird. Man unterscheidet zwischen dem statischen und dem dynamischen Aufruf-Graphen. Ersterer kann aus dem Programmtext abgeleitet werden, letzterer dagegen wird erst durch einen Programmlauf bestimmt. Um sich den Unterschied klarzumachen, denke man sich eine Funktion, die nach einer IF-Bedingung aufgerufen wird: Der statische Graph enthält sie immer, der dynamische nur dann, wenn die Bedingung zur Laufzeit erfüllt war. Da jedoch der CXpa (noch ?) keine graphische Schnittstelle hat, wird der Graph in Form einer Liste ausgegeben: Von der Spitze ausgehend werden die Routinen mit allen von ihnen direkt aufgerufenen Unterroutinen aufgelistet. In Klammern wird jeweils angegeben, wie oft eine Routine aufgerufen wurde. Rekursionen, d.h. Schleifen im Graphen, werden bei der ersten beteiligten Routine mit ``start of cycle'' gekennzeichnet.
Im Beispiel kommen zunächst einige Start-Routinen, etwa f_exit, bis das eigentliche Hauptprogramm aufgerufen wird, das vom Fortran-Compiler immer ``MAIN_'' genannt wird. Man sieht auch, daß der Compiler die ``DRAND''-Funktion in einen Aufruf von ``drand_$n'' verwandelt hat.