Application Compiler
Der Application-Compiler - eigentlich ein Pre-Compiler, denn er ruft den
normalen Fortran- und/ oder C-Compiler sowie den Loader auf - ist ein neues
Werkzeug von Convex zur Programm-Entwicklung. Er analysiert im Gegensatz zu
herkömmlichen Compilern nicht einzelne Routinen, sondern ein ganzes
Programm und legt eine umfangreiche Datenbasis darüber an. Auf diese Weise
ist er in der Lage, wesentlich weitergehende Fehlerprüfungen und
Optimierungen durchzuführen. In diesem Abschnitt wollen wir sehen, was er
für unser Beispielprogramm linalg ausrichten kann, wenn wir ihn auf
möglichst einfache Weise einsetzen, ohne weitere Analysen oder speziellere
Möglichkeiten auszunutzen.
Die Schnittstelle zum Application-Compiler ist das ''build''-Programm:
Ähnlich wie beim make muß man ein spezielles File namens ''Buildfile''
erstellen, das die Source-Files, Libraries und Optionen enthält.
Allerdings braucht man im Gegensatz zu make keine Abhängigkeiten
anzugeben, die findet der Compiler selbst heraus. Für gewiefte Optimierer
gibt es viele Optionen und Flags (s. Abschnitt 3.3.3); er arbeitet aber
sehr gut schon mit seinen Standard-Einstellungen.
Um den Application-Compiler eizusetzen, muß man den Such-Pfad erweitern um
das Verzeichnis tt /usr/convex/ipo/bin. Dann legt man im Verzeichnis mit den
Sourcen ein Buildfile (s.u.) an und startet den Compiler mit ''build''.
Falls alle benötigten Source-Files (und nur diese) in einem Directory
liegen und nur Fortran benutzt wird, genügt folgendes einfache Buildfile:
#
# alle Files im selben Directory wie dieses Buildfile, alle mit -O2
#
. -O2
link FORTRAN
options -o linalg -check all
Zunächst wollen wir den Application-Compiler zur Fehlersuche verwenden.
Wir extrahieren also mit ''make VERSION=1.1 source'' die fehlerhafte
Urversion von linalg und starten den Compiler mit
build |& tee Build.report
(Da die erzeugte Ausgabe umfangreich ist, leiten wir sie in das File
Build.report um. Um aber auch noch unmittelbar sehen zu können, was
passiert, verwenden wir das ''tee''-Filter, das seine Eingabe in ein File und
auf die Ausgabe schreibt.)
Zunächst erscheinen folgende Warnungen:
Warning: Argument number 1 of GAUSSJ has inconsistent type in
./main.f on line 57 and ./gaussj.f on line 1
Warning: Argument number 4 of GAUSSJ has inconsistent type in
./main.f on line 57 and ./gaussj.f on line 1
Warning: Argument number 1 of LUDCMP has inconsistent type in
./main.f on line 72 and ./ludcmp.f on line 1
Warning: Argument number 5 of LUDCMP has inconsistent type in
./main.f on line 72 and ./ludcmp.f on line 1
Warning: Argument number 1 of LUBKSB has inconsistent type in
./main.f on line 73 and ./lubksb.f on line 1
Warning: Argument number 5 of LUBKSB has inconsistent type in
./main.f on line 73 and ./lubksb.f on line 1
Warning: Argument number 1 of LUBKSB has inconsistent type in
./luinv.f on line 42 and ./lubksb.f on line 1
Warning: Argument number 5 of LUBKSB has inconsistent type in
./luinv.f on line 42 and ./lubksb.f on line 1
Nach einer Menge von Informationen zur Programm-Optimierung werden die
gefundenen Fehler noch einmal tabellarisch zusammengefaßt:
Errors Detected |
|
Wrong |
Mis- |
|
|
Scalar |
|
|
|
Mis- |
Number |
Matched |
|
Passed |
|
Variables |
|
Matched |
Of |
Return |
Invalid |
To |
Invalid |
Not |
Procedure |
Args |
Args |
Type |
Aliases |
Array |
SubScript |
Initialized |
LINALG |
6 |
|
|
|
|
|
|
GAUSSJ |
|
|
|
|
|
|
|
LUINV |
2 |
|
|
|
|
|
|
GETVEC |
|
|
|
|
|
|
|
ERNORM |
|
|
|
|
|
|
|
SETVEC |
|
|
|
|
|
|
|
TESTMT |
|
|
|
|
|
|
|
LUDCMP |
|
|
|
|
|
|
|
LUBKSB |
|
|
|
|
|
|
|
Totals |
8 |
|
|
|
|
|
|
build -check |
types |
types |
types |
|
|
arrays |
init |
Der Application-Compiler hat also einige der Fehler automatisch gefunden,
die wir vorher mühsam mit dem Debugger aufgespürt hatten.
Nun wollen wir sehen, was es mit dem verbesserten Optimieren auf sich hat.
Zunächst löschen wir die alte Datenbasis mit ''build -c'', dann holen wir
uns die Version 2.1, und starten wieder mit ''build''. Wir ignorieren die
umfangreiche Ausgabe bis auf die abschließende Fehlertabelle, die diesmal
keine Fehler anzeigt, und starten unser Programm mit ''/bin/time linalg''.
Mit dem Ergebnis erweitern wir unsere obige Laufzeittabelle der C3840 zu:
C3840: |
-no |
4.3 real |
4.1 user |
0.0 sys |
-O0 |
3.3 real |
3.2 user |
0.0 sys |
-O1 |
1.7 real |
1.6 user |
0.0 sys |
-O2 |
0.7 real |
0.6 user |
0.0 sys |
Appl.Comp. |
0.6 real |
0.5 user |
0.0 sys |
-O3 |
1.1 real |
1.3 user |
0.0 sys |
Ohne großen Aufwand hat der Application-Compiler das Programm linalg, das
an sich schon vom normalen Vektorisierer gut optimiert wird, um 11%
beschleunigt. Wie er das gemacht hat und wie man vielleicht noch mehr
erreichen kann, werden wir uns in den Abschnitten 3.3.1
und 4.2 ansehen.
Peter Junglas 18.10.1993