Kapitel 6 - Pipelining
|
Inhalt
|
- 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!
|
|
|
|
|
| Kapitel 1 | Einleitung |
|
Befehlsschleife, Risc und Cisc...
|
| Kapitel 2 | Interrupts |
|
Interrupts, Polling, DMA...
|
| Kapitel 3 | Speicherschutz |
|
Segmentation, Paging, Mapping, Multitasking...
|
| Kapitel 4 | Caches |
|
Lokalität, Cache-Arten, Schreibstrategien...
|
| Kapitel 5 | Risc |
|
Risc-Architektur, Load/Store, Registerfenster...
|
| Kapitel 6 | Pipelining |
|
Prinzip, Datenkonflikte, Forwarding, Delayed Load
|
| Kapitel 7 | Branch Prediction |
|
Statische / Dynamische Brach-Prediction...
|
| Kapitel 8 | Superskalarität |
|
Out-Of-Order Execution, Scoreboard und Tomasulo, VLIW...
|
| Kapitel 9 | Parallelrechner |
|
SMP,Vektorrechner, Cache-Kohärenz
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|