Compiler-Techniken für superskalare Prozessoren

Abhängigkeiten

Die Abhängigkeit zwischen der Instruktion 1 und 2 (1 schreibt r2, 2 liest r2 zum Vergleich) bedeutet einen RAW- (Read-after-Write-) Hazard. Die Konsequenz daraus ist eine Verzögerung der Ausführung, da keine parallele Ausführung möglich ist. Folgendes Bild stellt die Abhängigkeiten zwischen den einzelnen Instruktionen als Graph dar, und zwar getrennt nach Register- und Speicherabhängigkeiten.

Compiler-Bauer bezeichnen die dargestellte Abhängigkeit zwischen den Instruktionen 1 und 2 als Flussabhängigkeit. Den WAR- (Write-after Read-) Hazard zwischen den Instruktionen 6 und 9 nennen sie Anti-Abhängigkeit.

Die so genannte Output Dependence ist in dem Beispiel nicht direkt zu entdecken, sie existiert allerdings zwischen zwei Hintereinander-Ausführungen der Schleife. Dabei wird zum Beispiel in Instruktion 4 der gleiche Inhalt in ein Register geschrieben wie in Instruktion 3 beim nächsten Schleifendurchlauf. Die CompilerBauer bezeichnen diesen Zusammenhang als Output-Abhängigkeit, exakter als schleifenbedingte Output-Abhängigkeit (Loop-Carried Output Dependence).

Die bisherige Analyse für das Beispiel zeigt einen nur sehr geringen Anteil an paralleler Ausführung auf Instruktions-Level: Der IF-Teil führt pro Schleife neun Befehle in sechs Takten aus, die Performance beträgt also 1,5 Instruktionen pro Takt. Der Grund hierfür ist, dass die Kompilation viele Basisblöcke mit jeweils nur wenigen Befehlen geliefert hat.