next up previous
Nächste Seite: Leistungsgrenzen von M2Amiga Aufwärts: Die Register Vorherige Seite: Register-Variablen

Register-Erhaltung

Der Compiler erzeugt Code, der sich möglichst viele Werte in Registern merkt und entsprechend nutzt, um effizienten Code (Geschwindigkeit und Länge) zu generieren. Hierzu zählen Konstanten, ,,Level``, Library-Basen und auf Wunsch auch Zeiger.

,,Level`` bedürfen einer weiteren Erklärung: Falls eine lokale Prozedur auf Variablen oder Parameter einer weiter aussen liegenden Zugriff benötigt, muss sie sich zunächst am ,,static link`` (siehe 5.5.3) ,,entlanghangeln``. Dazu wird Code erzeugt, der bei einem späteren Zugriff auf denselben Level unterbleiben kann, wenn der angelegte Zeiger noch in einem Adressregister vorhanden ist.

Durch die Option ,,Volatile:=FALSE`` (Kommandozeile: -h) versucht der Compiler Zeiger folgender Art in Adressregistern zu halten:

BPOINTER (siehe 5.1.6) sind hiervon ebenso ausgenommen wie -Variablen!

Die Wirkung lässt sich wohl am ehesten als ,,vollautomatisches WITH`` (ohne Schreiberleichterung) umschreiben. Dies spart sehr viel Code, unter Umständen mehr als ein echtes WITH. Ein echtes WITH kann natürlich mehr (WITH x^.y^ oder WITH x^[y]), hat aber den Nachteil, dass ein Adressregister blockiert wird, wohingegen bei diesem Verfahren der Register-Erhaltung bei ,,Registermangel`` einfach der Inhalt vergessen und bei Bedarf neu geladen werden kann.

Der Compiler geht sehr vorsichtig vor, indem er nach einem Prozeduraufruf immer von dem ,,schlimmsten Fall`` ausgeht, dass alle Objekte, auf die die Prozedur Zugriff hat, zerstört sind (globale Prozeduren haben z.B. keinen Zugriff auf die lokalen Variablen und Werte-Parameter). Ebenfalls als zerstört gelten Zeiger selbstverständlich nach direkten Zuweisungen und nach der Benutzung als VAR-Parameter eines Prozedur-Aufrufs.

Dennoch kann die Strategie leicht zu Fall gebracht werden, indem irgendein Zeiger auf eine der oben genannten Variablen zeigt und deren Wert verändert. Damit hat dann die Variable im Speicher einen anderen Wert als das Register. Dies kann der Compiler nicht feststellen! Aus diesem Grunde wird diese Optimierung auch nur auf Wunsch vorgenommen.


\begin{example}
Ein Beispiel, bei dem die Option ,,Volatile:=FALSE\lq\lq  zu fehlerha...
... einem --- schwierig zu findenden ---
Programmfehler f\uml {u}hrt.
\end{example}

Als Faustregel kann man sagen, dass Prozeduren und Moduln, die nicht mit Zeigern oder Listen arbeiten, immer mit der Option ,,Volatile:=FALSE`` kompiliert werden können. Der Vorteil liegt dabei im Merken der Adressen von VAR-Parametern.

Sobald Zeiger auf globale oder lokale Variablen zeigen, insbesondere bei Listenverarbeitung sollte die Option immer auf TRUE gesetzt sein! Wenn dennoch unbedingt Code eingespart werden soll, kann die (unschöne) Methode des Ausprobierens helfen. Im Compiler selbst musste nur eine einzige Prozedur mit ,,Volatile:=TRUE`` kompiliert werden.


next up previous
Nächste Seite: Leistungsgrenzen von M2Amiga Aufwärts: Die Register Vorherige Seite: Register-Variablen
Claudio Nieder 2000-11-12