Information Technology Reference
In-Depth Information
Natürlich ist es möglich, den prozentualen Einfluss der Decodierzeit auf die Arbeits-
geschwindigkeit eines virtuellen Prozessors zu vermindern, indem komplexe
Befehle, z.B. trigonometrische Funktionen, eine Fast Fourier Transformation usw.
vorgesehen werden - die Zeit für die Decodierung fällt hierbei wegen des Aufwands
der Ausführung nicht mehr ins Gewicht. Da die entsprechenden Befehle jedoch in
den meisten Anwendungen kaum eine Bedeutung haben, lassen sich auf diese Weise
vor allem Interpreter verbessern, die auf bestimmte Aufgaben spezialisiert sind, z.B.
die Abfrage von Datenbanken (ABAP [91]) oder die Automatisierung einfacher
Internet-Anwendungen (perl [153]).
Für die folgenden Betrachtungen von größerer Bedeutung sind Optimierungstechni-
ken, die sich auch dann anwenden lassen, wenn ein virtueller Prozessor mit einer zu
realen Prozessoren vergleichbaren Funktionalität implementiert werden soll. Zwei
grundsätzliche Verfahrensweisen sind unterscheidbar: (1.) die architekturunabhän-
gige Programmoptimierung, z.B. unter Nutzung der Möglichkeiten des interpretie-
renden realen Prozessors und (2.) die architekturabhängige Programmoptimierung,
bei der Änderungen des virtuellen Programmiermodells in Kauf zu nehmen sind.
Das Programm in Bild 4.1 lässt sich z.B. architekturunabhängig durch Zusammen-
ziehen der in den Zeilen 2 und 15 stehenden Anweisungen nach vorangehendem
Tausch der Zeilen 2 und 3 oder durch Verwendung realer Register optimieren (siehe
Beispiel 4.1). Architekturabhängig ist der im Bild dargestellte Interpreter auch
durch Verwendung eines 0-Adress- statt eines 3-Adressdatenwerks optimierbar. Da
0-Adressbefehle nur einen Operationscode enthalten, lassen sich so die zwischen
den Zeilen 4 und 7 stehenden Anweisungen vermeiden. Dies mag ein Grund dafür
sein, weshalb Interpreter oft virtuelle Prozessoren mit 0-Adressarchitektur imple-
mentieren. Zu nennen sind z.B. die mit Forth verwendeten Laufzeitumgebungen
[204], der P-Code-Interpreter von Pascal [140, 30] und die virtuelle Java-Maschine
JVM [99].
Beispiel 4.1. Optimierung von Interpretern . Zur Verbesserung der Arbeitsgeschwindigkeit des in
Bild 4.1 dargestellten virtuellen Prozessors ist es möglich, die Variablen pc, instr, opcode, a, b, d
und, falls nicht durch Umstellung des Programms unnötig geworden, npc in realen Registern zu
speichern. Im Allgemeinen ist dies jedoch nicht mit dem Datenspeicher möglich. Zwar verfügen
viele reale Prozessoren über einen Registerspeicher mit ausreichender Kapazität, normalerweise
kann auf diesen jedoch nicht indirekt (besser indirektindiziert) zugegriffen werden, wie hier in den
Zeilen 5, 6, 9 und 10 notwendig. Pro Schleifendurchlauf sind somit drei Datenspeicherzugriffe
erforderlich, die zwar vom Datencache bedient, jedoch trotzdem langsamer bearbeitet werden dürf-
ten als Zugriffe auf die realen Register. Eine Möglichkeit zur Lösung dieses Problems besteht darin,
die indirekte Adressierung des virtuellen Datenspeichers mit Hilfe einer Fallunterscheidung nach-
zubilden. Bild 4.2a zeigt ein entsprechend abgewandeltes Programm.
Anstatt den virtuellen 3-Adressbefehl in seine Einheiten zu zerlegen und diese anschließend einzeln
zu verarbeiten, wird der Befehl als ganzes decodiert und einer Operation zugeordnet. Die hierbei zu
verknüpfenden Operanden und das Ergebnis müssen nicht mehr indirekt, sondern können direkt
adressiert werden, wodurch die Verwendung von realen Registern möglich wird (hier data0 bis
data7). Als Nachteil muss jedoch eine sehr viele Alternativen berücksichtigende Fallunterscheidung
in Kauf genommen werden. Zum Beispiel sind mit 16 Bit breiten Befehlen 65536 Befehlscodes zu
differenzieren. Zwar ist dies tolerierbar, wenn der Befehlscache des realen Prozessor ausreichend
groß ist, um den Interpreter vollständig aufnehmen zu können, nicht jedoch, wenn mit jedem
Schleifendurchlauf Zugriffe auf den prozessorexternen Befehlsspeicher erforderlich sind.
Search WWH ::




Custom Search