Wikipedia · einfach zusammengefasst · Stand
Registerumbenennung
Registerumbenennung (englisch register renaming) bezeichnet eine Phase in der Befehlsdekodierung, die meist von superskalaren Mikroprozessoren angewandt …
Inhalt4 Abschnitte
Zweck und Grundidee
Registerumbenennung (englisch register renaming) ist eine Phase der Befehlsdekodierung, die meist in superskalaren Mikroprozessoren eingesetzt wird. Superskalar bedeutet, dass ein Prozessor mehrere Befehle gleichzeitig bearbeiten kann. Die Registerumbenennung verhindert dabei unnötige Sequentialisierung und verbessert die Out-of-Order-Execution: Kleine, voneinander unabhängige Programmteile können parallel oder in einer anderen Reihenfolge ausgeführt werden.
Superskalare Prozessoren besitzen nur eine verhältnismäßig kleine Zahl direkt ansprechbarer Architekturregister. Diese Register sind durch den Befehlssatz festgelegt. Neue Prozessorgenerationen können nicht einfach zusätzliche Register in den Befehlssatz aufnehmen, weil dadurch die Binärkompatibilität mit vorhandenen Programmen verloren gehen könnte. Werden dieselben Registernamen für verschiedene Zwischenergebnisse verwendet, entstehen deshalb scheinbare Datenabhängigkeiten. Diese sogenannten Namensabhängigkeiten oder Datenkonflikte verhindern eine parallele Ausführung, obwohl zwischen den betreffenden Berechnungen keine echte inhaltliche Abhängigkeit besteht.
Funktionsweise und Abhängigkeiten
Zur Registerumbenennung verfügt der Prozessor über viele physisch vorhandene Schattenregister, die ein Programm nicht direkt ansprechen kann. In der Dekodierstufe (ID) wird das Zielregister einer definierenden Instruktion einem solchen Schattenregister zugeordnet. Eine definierende Instruktion ist hier ein Befehl, der ein Ergebnis erzeugt und in einem Register speichern will.
Dadurch können zwei Arten unechter Abhängigkeiten aufgelöst werden:
- Write After Read (WAR): Ein späterer Befehl will ein Register überschreiben, aus dem ein früherer Befehl zunächst noch lesen muss.
- Write After Write (WAW): Zwei Befehle wollen nacheinander in dasselbe Register schreiben.
Nach der Umbenennung bleiben im Code nur echte Datenabhängigkeiten bestehen. Dazu gehört insbesondere Read After Write (RAW): Ein Befehl benötigt tatsächlich das Ergebnis, das ein früherer Befehl erst erzeugen muss. Unabhängige Befehle können dagegen parallel oder in geänderter Reihenfolge ausgeführt werden.
In der x86-Familie wurde Registerumbenennung erstmals im Pentium Pro eingesetzt. Dort wurden acht für Programmierer sichtbare und im Befehlscode ansprechbare Register auf 96 physisch vorhandene, aber nicht direkt ansprechbare Register abgebildet.
Beispiel einer Umbenennung
Im ursprünglichen Programm stehen folgende Befehle:
1: R1 := R2 / R3 2: R4 := R1 + R5 3: R5 := R6 + R7 4: R1 := R8 + R9
Zwischen Zeile 1 und Zeile 2 besteht eine RAW-Abhängigkeit, weil Zeile 2 das zuvor in R1 berechnete Ergebnis benötigt. Zwischen Zeile 2 und Zeile 3 liegt eine WAR-Abhängigkeit vor: Zeile 2 muss R5 lesen, bevor Zeile 3 diesen Registernamen überschreibt. Zwischen Zeile 1 und Zeile 4 besteht eine WAW-Abhängigkeit, weil beide Befehle in R1 schreiben. In dieser Form muss der Code daher sequentiell abgearbeitet werden.
Werden die Zielregister der definierenden Operationen konsequent umbenannt, ergibt sich:
1: A := R2 / R3 2: B := A + R5 3: C := R6 + R7 4: D := R8 + R9
Die echte RAW-Abhängigkeit zwischen Zeile 1 und Zeile 2 bleibt erhalten: Zeile 2 benötigt weiterhin das Ergebnis A aus Zeile 1. Die WAR- und WAW-Abhängigkeiten verschwinden dagegen, weil die Ergebnisse in verschiedene Schattenregister geschrieben werden. Damit bilden die Zeilen 1 und 2 einen zusammengehörigen Block; dieser Block sowie die unabhängigen Zeilen 3 und 4 können in beliebiger Reihenfolge oder parallel ausgeführt werden.
Alternative beim Itanium
Beim Itanium-Prozessor wurde mit Explicitly Parallel Instruction Computing ein anderer Ansatz verfolgt, der sich jedoch als weniger erfolgreich erwies. Dabei wird bereits im Programmcode festgelegt, welche Anweisungen parallel ausgeführt werden können. Diese Anweisungen werden in besonderen Instruktionen kodiert und zu sogenannten Anweisungsblöcken (instruction groups) zusammengefasst.
Ein Nachteil besteht darin, dass der Zielprozessor schon bei der Übersetzung bekannt sein muss. Eine spätere Anpassung an einen anderen Prozessor ist nicht oder nur durch erneutes Übersetzen möglich. Bei der Registerumbenennung entscheidet dagegen der Prozessor während der Befehlsverarbeitung anhand seiner vorhandenen physischen Register, welche Namensabhängigkeiten beseitigt werden können.