Eine Pipeline muss immer dann Pipelinestufen anhalten, wenn dort Daten benötigt werden, die noch nicht vorhanden sind (da diese Daten erst noch von den Befehlen in den vorausgehenden Pipelinestufen erzeugt werden). Meist werden die Register von der letzten Pipelinestufe geschrieben, so dass keine WAW und keine WAR-Konflikte mehr vorliegen können. Übrig bleiben die RAW-Konflikte und die Konflikte der Sprungbefehle (die im Grunde auch RAW-Konflikte durch den PC sind).
Um die Zahl der NOPs zu bestimmen, ist die folgende Folie 164 aus dem Kapitel hilfreich: Dabei können wir die Zahl der NOPs für eine Pipeline mit beliebig vielen Pipelinestufen bestimmen, wenn wir folgende Stufen kennen:
- pIF ist die Stufe, in der neue Befehel gelesen werden
- pID ist die Stufe, in der Operandenregister gelesen werden
- pEX ist die Stufe, in der ALU-Ergebnisse verfügbar sind
- pMA ist die Stufe, in der Speicherzugriffe verfügbar sind
- pWB ist die Stufe, in der Register geschrieben werden
Dann ist die folgende Anzahl von NOPs erforderlich, um den Mindestabstand von Befehlen, die ein Register lesen zu den vorausgehenden Befehlen, die dieses Register zuletzt schreiben, einzuhalten:
| no forward, no bypass | no forward+bypass | forward+bypass |
---|
nach ALU | pWB-pID | pWB−pID-1 | pEX−pID-1 |
---|
nach LOAD | pWB−pID | pWB−pID-1 | pMA−pID-1 |
---|
nach Branch | pWB−pIF | pWB−pIF-1 | pEX−pIF-1 |
---|
Bei Sprüngen haben wir immer einen Konflikt, da der PC immer beim nächsten Befehl gelesen werden muss. Ansonsten muss man die RAW-Konflikte bestimmen. Für die Standard-Pipeline bedeutet dies:
| no forward, no bypass | no forward+bypass | forward+bypass |
---|
nach ALU | 3 | 2 | 0 |
---|
nach LOAD | 3 | 2 | 1 |
---|
nach Branch | 4 | 3 | 1 |
---|
Der Befehl ld $4,$7,$4 hat einen RAW-Konflikt zu dem darauf folgenden Befehl addu $1,$1,$4. Da ld $4,$7,$4 ein LOAD-Befehl ist, müssen wir rechts (mit Forwarding) ein NOP einfügen und links (ohne Forwarding) sogar 2 NOPs, um den Mindestabstand zwischen den beiden Befehlen einzuhalten.
Der Befehl ld $4,$7,$3 hat keinen RAW-Konflikt zum direkt darauf folgenden Befehl, aber zu dem Befehl ld $4,$7,$4 der 2 Befehle nachfolgt. Wir brauchen hier keine NOPs, da bereits ohne Forwarding der Mindestabstand 2 eingehalten wird.
Hilfreich ist hier folgendes Tool zur Analyse der Konflikte https://es.cs.uni-kl.de/tools/teaching/AbacusConflictAnalysis.html mit dem folgenden Programm:
mov $1,0
mov $2,8
mov $3,0
mov $7,0
ld $4,$7,$3
mov $7,8
ld $4,$7,$4
addu $1,$1,$4
addiu $3,$3,1
sltu $4,$3,$2
bnz $4,-7
mov $7,0
Ebenso der Simulator https://es.cs.uni-kl.de/tools/teaching/AbacusSim.html, der die Konflikte ganz genau bestimmt.