Grundlagen zu Intels Itanium (Teil I)

Rechnen in epischer Breite

Die Itanium Architektur definiert eine superskalare Prozessorarchitektur. Eine solche Architektur besitzt mehrere Recheneinheiten (Arithmetic Logic Unit, ALU) und ist dadurch in der Lage, in jedem Taktschritt mehrere Befehle gleichzeitig abzuarbeiten. Entscheidend ist dabei, die ALUs immer mit unabhängigen, parallel ausführbaren Instruktionen zu füttern.

Die meisten superskalaren Prozessoren, nicht aber der Itanium, basieren dazu auf einer RISC-Architektur mit Out-of-Order Execution. Dabei werden mehrere Befehle in einem Puffer bereitgehalten, die der Prozessor in beliebiger Reihenfolge ausführt, sobald eine passende Berechnungseinheit frei ist und die benötigten Operanden vorhanden sind.

Die so berechneten Ergebnisse speichert die CPU dann wieder in der Reihenfolge ab, die durch die ursprüngliche Reihenfolge der Befehle im Befehlsstrom vorgegeben ist (Ergebnissequenzialität).

Für die Out-of-Order Execution muss der Prozessor Abhängigkeiten zwischen den Befehlen erkennen, die verwendeten Register umbenennen, Ergebnisse intern umsortieren und sich auch im Falle einer Unterbrechung durch einen Interrupt nach außen wie ein In-Order-Prozessor geben. All dies erfordert eine komplexe Hardware-Schaltung mit hohem Platzbedarf auf dem Die und sorgt für zusätzliche Stufen in der Bearbeitungs-Pipeline.

Mit EPIC (Explicit Parallel Instruction Computing) beschreitet Intel bei der IA-64 einen anderen Weg. EPIC basiert auf dem VLIW Very Long Instruction Word)-Prinzip. Hier wird ein sehr breites Befehlswort in mehrere Felder unterteilt, die einzelne unabhängige Instruktionen enthalten. Bei der Programmausführung liest die CPU das lange Befehlswort ein und leitet die darin enthaltenen Instruktionen an voneinander unabhängige Ausführungseinheiten weiter. Die Auswahl der parallel ausführbaren Befehle bleibt somit dem Compiler überlassen. Dieser hat beim Erzeugen des Codes einen sehr viel weiteren Blick für den Programmkontext als eine Hardware innerhalb der CPU zur Laufzeit. Deshalb kann der Compiler unabhängige Instruktionen viel effektiver zusammenstellen.