Pipeline-Hazards sind Situationen, in denen die nächste Stufe einer CPU-Pipeline einen Befehl nicht wie geplant im nächsten Takt ausführen kann. Das Fließband-Prinzip verspricht einen Befehl pro Takt; ein Hazard kostet genau diesen Takt (oder mehr), weil eine Stufe warten muss. Man unterscheidet drei Klassen.

Strukturelle Hazards

Zwei Befehle brauchen im selben Takt dieselbe Hardware-Einheit, etwa die eine Speicherschnittstelle oder einen ALU-Port. Die Ressource ist überbucht. Moderne CPUs begegnen dem, indem sie kritische Ressourcen verdoppeln: getrennte Wege und Caches für Instruktionen und Daten folgen dem Harvard-Prinzip (siehe Von-Neumann-Architektur). Reicht das nicht, wird ein Stall-Takt eingefügt.

Daten-Hazards

Ein Befehl braucht ein Ergebnis, das ein vorheriger Befehl erst noch erzeugt. Die klassische Taxonomie unterscheidet drei Ausprägungen:

  • RAW (Read After Write): echte Abhängigkeit, der Nachfolger liest, was der Vorgänger schreibt. Sie ist der kritische Fall und wird durch Forwarding (auch Bypassing) entschärft: Das Ergebnis wird direkt aus der Ausführungsstufe zur nächsten Instruktion zurückgeleitet, ohne den Register-Rückschreibetakt abzuwarten. Forwarding beseitigt die meisten ALU-RAWs vollständig.
  • WAR (Write After Read), auch Anti-Abhängigkeit: Der Nachfolger schreibt ein Register, das der Vorgänger noch lesen will. Eigentlich nur ein Artefakt der Registerbelegung.
  • WAW (Write After Write), auch Output-Abhängigkeit: Zwei Befehle schreiben dasselbe Register, die Reihenfolge der sichtbaren Werte muss stimmen.

WAR und WAW entstehen klassisch, weil es nur wenige architektonische Register gibt. Out-of-Order-Prozessoren lösen sie durch Register-Renaming: Jede Schreiboperation bekommt ein frisches physisches Register, scheinbare Abhängigkeiten verschwinden. Echte RAW-Abhängigkeiten bleiben und werden über Forwarding und das dynamische Scheduling des superskalaren Schedulers behandelt.

Kontroll-Hazards

Bei einem Sprungbefehl weiß die Pipeline erst nach der Auswertung, ob der Sprung genommen wird. Moderne Prozessoren raten mit Branch Prediction; bei einer falschen Vorhersage werden die spekulativ geholten Befehle verworfen und die Pipeline neu gefüllt. Die Kosten entsprechen der Pipelinelänge in Takten. Historische MIPS-Prozessoren nutzten stattdessen Verzögerungsslots: Der Befehl direkt nach dem Sprung wird immer noch ausgeführt.

Lösungen im Zusammenspiel

Hardware und Compiler arbeiten zusammen. Der Compiler verschiebt unabhängige Befehle über Lücken hinweg (Instruction Scheduling, Teil der Codegenerierung), die Hardware erledigt Forwarding, Stalls und Renaming in der Mikroarchitektur. Die Register-Bank mit mehreren Lese- und Schreibports liefert die Grundlage dafür.

Verwandte Grundlagen: Pipelining (das Fließband-Prinzip), Opcode (die Befehlsformate im Taktstrom), Instruktionssatz (die sichtbare Befehlsschnittstelle).