Kapitel 6 - Pipelining
- Wozu ist Pipelining gut?
- Aufbau einer Pipeline
- Die drei Konflikte
- Forwarding und Delayed-Load
Wozu Pipelining?
Pipelining soll es ermöglichen Befehle überlappt auszuführen. Dazu sind ein
einheitliches Befehlsformat fester Länge Grundlage. Deshalb werden werden nur auf
Register getätigt. Für Speicheroperationen wird die LOAD / STORE Philosophie
verfolgt, um langsame Hauptspeicherzugriffe zu minimieren.
Was ist Voraussetzung für Pipelining?
Die Befehlsverarbeitungsphase muss sich in mehrere voneinander unabhängige
Phasen unterteilen lassen. Die einfachste Form einer Pipeline ist die 5-stufige mit
folgenden Phasen:
- Befehl holen
- Befehl dekodieren
- Befehl ausführen
- Auf Speicher zugreifen
- Ergebnis in Register schreiben
Moderene CPU's haben weitaus komplexere Pipelines, in denen die einzelnen
Stufen wiederrum in mehrere sich überlappende Phasen aufgeteilt werden.
Der allgemeine Aufbau einer (fünfstufigen) Pipeline
Um Parallelität in der Befehlsausführungsphase zu erreichen, wird der
Datenpfad so konstruiert, daß folgende (hier fünf) Phasen unabhänig voneinander
arbeiten können. Nur so ist es möglich eine verzahnte Abarbeitung mehrerer Befehle
zu erreichen.

Somit wird ,nachdem eine Pipeline gefüllt ist, im Optimalfall pro Takt ein Befehl
fertig. (CPI = 1)
Welche Pipeline-Konflikte müssen behandelt werden?
Datenabhängigkeiten (Data Hazards)
Sind logische Abhängigkeiten, welche eine verzögerte Abarbeitung erfordern,
weil z.B. ein Folgebefehl auf ein Ergebnis eines anderen Befehles warten muss.
Jump- / Branchverzögerungen (Control Hazards)
Bei Sprungbefehlen liegt oft das Sprungziel nach der Dekodieung noch nicht
fest. Somit müssen Techniken eingesetzt werden um diese Wartezeiten zu minimieren.
(Branch Prediction)
Ressourcenkonflikte (Structural Hazards)
Bei bestimmten Befehlskombinationen ist es unter Umständen möglich, daß ein
Teilwerk seine Arbeit wiederholen muss. Solche Ressourcenkonflikte treten dann auf,
wenn nicht jeder Teilphase völlig unabhängige Teilwerke zugeordnet sind. Ein
Beispiel ist z.B. ein zeitgleicher Lesezugriff eines LOAD/STORE Befehles, welcher
sich zwangsweise mit einem eventuellen MEM ACCESS eines anderen Befehles
überschneidet.
Abhilfe können hier Dual-Port RAM, Havard-Architektur oder getrennte Code- und
Datencaches schaffen.
Welche drei verschiedenen Datenabhängigkeiten gibt es?
RAW, WAW und WAR-Konflikte sind Datenabnhänigkeiten, welche in Pipelines
auftreten können. Dabei ist das RAW-Problem für Pipelines typisch. WAR Konflikte
treten eher bei Out-Of-Order Execution auf. Um Read-After-Write Konflikte
aufzulösen, gibt es verschiedene Ansätze wie Softwarelösungen (
Compileroptimierung), Scoreboarding (zentrale Steuerlogik) und Forwarding
(zusätzlicher Datenpfad).
Was ist Forwarding?
Beim Forwarding wird ein Bypass eingerichtet, welcher ein Ergebniss einer
Operation schon einem Folgebefehl zur Verfügung stellt, bevor es überhaupt in ein
Register geschrieben wurde. Aber trotz Load-Forwarding hat ein Ladebefehl eine
Verzögerung, welche nicht gänzlich eliminiert werden kann. In diesem Fall kann die
Delayed-Load Technik oder auch eine Befehlsumordnung Anhilfe schaffen.
Was ist die Delayed Load-Technik?
Bei der Delayed Load-Technik wird die Verzögerung nach einem LOAD Befehl als
architektonisches Merkmal angesehn und den Compilerbauern offengelegt. Diese können
nun durch Befehlsumordnungen versuchen, nach einem LOAD-Befehl einen
datenunabhängigen Befehl einzufügen, um den Slot zu füllen.
Zusammenfassung Pipelining
Pipelines werden in allen modernen CPUs benutzt. Die UltraSparc2 hat neun und
der P2 zwölf Stufen. Der Intel Pentium Itanium weißt eine 20 stufige Superpinepline
(pipeline in der sich einzelne Stufen überlappen können) auf! Pipes werden
heutzutage in Kombination mit der Superskalartechnik verwendet, um höchste
Effizienz und Parallelverarbeitung gewährleisten zu können. Die fünf grundlegenden
Stufen einer einfachen Pipeline sind IF,ID,EX,MEM und WB.
Takte T = Befehle + (Pipestufen - 1)
Folgende Abhängigkeiten verhindern, dass die CPI auf eins gehen:
Strucual Hazards bzw. Ressourcenkonflikte
IF und MEM wollen gleichzeitig auf Speicher lesend oder schreibend zugreifen.
Das geht nicht, außer bei Dual-Port-RAM, welcher aber sehr teuer ist. Dieses
Problem tritt aber bei modernen CPU's kaum noch auf, da eh intern eine
Havard-ähnliche Architektur mit getrenntem Befehls- und Datencache gearbeitet wird.
Data Hazards bzw. Datenabhängigkeiten
Ein Folgebefehl wartet auf das Writeback der darüber liegenden Pipe, da er von
diesem Befehl abhängig ist. Dies kann durch Nops bzw. Stalls ineffizient gelöst
werden. Besser der Programmierer oder der Compiler löst diese Abhängigkeiten durch
eine clevere Umordnung der Befehlsfolge auf. Es gibt aber noch eine andere
Möglichkeit, welche aber hardwareseitig unterstützt werden muss. (VLIW,
Superskalar)
Forwarding
Beim Forwarding werden Ergebnisse, sobald sie vorliegen an die nächste Stufe
weitergereicht und nicht erst auf das Write Back gewartet. In anderen Worten: Das
Ergebnis der ALU wird dieser sofort wieder eingespeist.
Control Hazards bzw. Sprungverzögerungen
Sprungergebnisse stehen erst in der Write Back Phase an. Moderne Prozessoren
haben aber schon in der Fetch/Decode-Einheit eine Logik, welche die Zieladresse des
Sprunges berechnet. Eine andere Möglichkeit ist die des spekulativen Ausführens.
Hier tritt aber das Problem auf, dass viel Aufwand bei falscher Spekulation
getrieben werden muss.
Was ist der Unterschied zwischen echten und unechten Datenabhängigkeiten?
Echte Datenabhängigkeiten sind RAW-Konflikte, bei dem ein Befehl auf die
Beendigung eines Anderen warten muss, da er das Ergebnis als Operand benötigt.
Unechte Datenabhängigkeit sind Abhängigkeiten, welche nur durch Namensabhängigkeit
entstehen.
Es gibt zwei Arten unechter Datenabhängigkeit:
Antidependence sind WAR-Konflikte, welche entstehen, wenn ein
Folgebefehl auf ein Register schreiben möchte, das noch von einem Anderen benutzt
wird.
Output Dependece sind WAW-Konflikte, welche entstehen, wenn
mehrere Befehle auf ein und das selbe Register schreiben. Hier muss sichergestellt
werden, daß die Schreibreihenfolge der der Befehle entspricht.
Beide Abhängigkeiten können durch Register Renaming vermindert
werden!
|
|
|
|
|
|
|
|
|
|
|
Quellen:
|
Andrew S. Tanenbaum
Computerarchitektur
|
Andrew S. Tanenbaum
Moderne Betriebssysteme
|
Petterson
Computer Architectur & Design
|
Christian Märtin
Rechnerarchitekturen
|
Rehm
Skript und Vorlesung
|
Word Wide Web
Verschiedenste Seiten
|
|
|
|
|