Esercizio 24pipeline MIPS senza forwarding, numero di cicli
In questa pagina 5
Testo (esempi di compitino di Architettura degli Elaboratori, UniPD, a.a. 2014-15 e 2015-16, quesito 3 a risposta multipla). Sia data la seguente sequenza di istruzioni assembler (i dati immediati sono in esadecimale):
LW $5, 80($0)
SUB $2, $0, $3
LW $3, 800($2)
SUBI $3, $3, 3
ADDI $2, $2, 4
SW $3, 108($2)
SUB $4, $5, $3Si consideri la pipeline MIPS a 5 stadi vista a lezione, senza possibilità di data-forwarding, ma con possibilità di scrittura e successiva lettura dei registri in uno stesso ciclo di clock. L'esecuzione completa del codice avviene in un numero di cicli pari a: a) 13; b) 15; c) 19; d) 17; e) nessuna delle precedenti.
(Nel compitino 2015-16 il codice è SW $3, 80($0), ADD $2, $3, $1, LW $1, 800($2), SUBI $1, $1, 3, ADDI $2, $2, 4, SW $1, 108($2), SUB $4, $3, $1 con le opzioni a) 13, b) 15, c) 19, d) 14, e) nessuna delle precedenti.)
Teoria: PipelineIdea della catena di montaggio; pipeline a 5 stadi IF, ID, EX, MEM, WB; tempo di ciclo, tempo per n istruzioni in una pipeline a k stadi e speedup con esempi svolti; registri di pipeline; scrittura e lettura dei registri nello stesso ciclo; limiti (stadi sbilanciati, hazard).Pipeline →, Hazard nella pipelineHazard strutturali, sui dati e sul controllo; dipendenze RAW, WAR e WAW; stalli e bolle con diagrammi; data forwarding (bypass) e caso load-use; riordino delle istruzioni da parte del compilatore e dell'hardware; costo dei salti.Hazard nella pipeline →. Esercizi analoghi: Esercizio 18 · dipendenze RAW e WAW in un frammento MIPS, Esercizio 19 · speedup di una pipeline con salti.
Regola per contare gli stalli
Pipeline a 5 stadi: IF, ID (lettura dei registri), EX, MEM, WB (scrittura dei registri). Senza forwarding un'istruzione che legge un registro scritto da una precedente deve avere il proprio ID nello stesso ciclo del WB della produttrice, o dopo (il WB scrive nella prima metà del ciclo e l'ID legge nella seconda). Se la produttrice ha IF al ciclo , il suo WB è al ciclo (senza stalli propri), quindi il consumatore, che a regime avrebbe ID al ciclo ( = distanza in istruzioni), deve aspettare:
| distanza tra produttrice e consumatrice | cicli di stallo |
|---|---|
| 1 (istruzione successiva) | 2 |
| 2 | 1 |
| 3 o più | 0 |
Durante lo stallo l'istruzione resta in ID e quella dopo resta in IF. Gli stalli si sommano perché ciascuno ritarda tutte le istruzioni successive. Numero di cicli: ( stalli).
Individuare le dipendenze
Per ogni istruzione i registri letti (R) e quello scritto (W):
| # | istruzione | scrive | legge | dipendenza (RAW) |
|---|---|---|---|---|
| 1 | LW $5, 80($0) |
$5 |
$0 |
|
| 2 | SUB $2, $0, $3 |
$2 |
$0, $3 |
|
| 3 | LW $3, 800($2) |
$3 |
$2 |
$2 da 2, distanza 1 → 2 stalli |
| 4 | SUBI $3, $3, 3 |
$3 |
$3 |
$3 da 3, distanza 1 → 2 stalli |
| 5 | ADDI $2, $2, 4 |
$2 |
$2 |
$2 da 2, distanza 3 → 0 stalli |
| 6 | SW $3, 108($2) |
memoria | $3, $2 |
$3 da 4, distanza 2 → 1 stallo; $2 da 5, distanza 1 → 2 stalli (conta il peggiore: 2) |
| 7 | SUB $4, $5, $3 |
$4 |
$5, $3 |
$5 da 1, distanza 6; $3 da 4, distanza 3 → 0 stalli |
Per l'istruzione 6 le due attese avvengono in parallelo (si aspetta che entrambi i registri siano pronti): si prende il massimo, non la somma. Gli stalli totali sono .
Diagramma
| istruzione | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
LW $5, 80($0) |
IF | ID | EX | MEM | WB | ||||||||||||
SUB $2, $0, $3 |
IF | ID | EX | MEM | WB | ||||||||||||
LW $3, 800($2) |
IF | ID | ID | ID | EX | MEM | WB | ||||||||||
SUBI $3, $3, 3 |
IF | IF | IF | ID | ID | ID | EX | MEM | WB | ||||||||
ADDI $2, $2, 4 |
IF | IF | IF | ID | EX | MEM | WB | ||||||||||
SW $3, 108($2) |
IF | ID | ID | ID | EX | MEM | WB | ||||||||||
SUB $4, $5, $3 |
IF | IF | IF | ID | EX | MEM | WB |
- Istruzione 3:
$2è scritto daSUBnel WB del ciclo 6 → l'ID diLWva dal 4 al 6 e l'EX parte al 7. - Istruzione 4:
$3è scritto daLW $3nel WB del ciclo 9 → l'ID diSUBIfinisce al 9, EX al 10. - Istruzione 5:
$2viene letto in ID al ciclo 10, dopo il WB diSUB(ciclo 6): nessuna attesa. - Istruzione 6:
$2daADDI(WB al ciclo 13) e$3daSUBI(WB al ciclo 12) → ID fino al 13, EX al 14. - Istruzione 7: nessuna attesa; l'ID viene però ritardato dall'attesa dell'istruzione davanti (stalli propagati), e
WBal ciclo 17.
Totale: cicli → risposta d.
Versione 2015-16. Le dipendenze hanno la stessa forma (ADD → LW, LW → SUBI, ADDI e SUBI → SW; SUB finale non dipende da nulla di vicino): stessi 6 stalli, 17 cicli, che non è tra le opzioni a) 13, b) 15, c) 19, d) 14 → risposta e (nessuna delle precedenti). Le altre opzioni non corrispondono a un conteggio corretto: sono distrattori (chi ignora gli stalli di una delle dipendenze, o ne conta meno per istruzione).
Verifica con un programma
import re
def cicli(codice):
"""Pipeline MIPS a 5 stadi: scrittura WB nella prima metà del ciclo e lettura ID nella seconda."""
ins = []
for riga in codice:
op, resto = riga.split(None, 1)
args = [a.strip() for a in resto.split(",")]
if op in ("LW", "SW"):
base = re.search(r"\((\$\d+)\)", args[1]).group(1)
scrive = args[0] if op == "LW" else None
legge = [base] + ([args[0]] if op == "SW" else [])
else:
scrive, legge = args[0], [a for a in args[1:] if a.startswith("$")]
ins.append((op, scrive, legge))
ex, id_first, if_first = [], [], []
for i, (op, scrive, legge) in enumerate(ins):
ifc = 1 if i == 0 else id_first[i - 1] # entra in IF quando la precedente lascia IF
idc = ifc + 1 if i == 0 else max(ifc + 1, ex[i - 1]) # entra in ID quando la precedente passa a EX
e = idc + 1
for r in legge:
for p in range(i - 1, -1, -1):
if ins[p][1] == r:
wb = ex[p] + 2
e = max(e, wb + 1) # ID (ciclo e-1) nel ciclo del WB o dopo
break
if_first.append(ifc); id_first.append(idc); ex.append(e)
return ex[-1] + 2
codice_1415 = ["LW $5, 80($0)", "SUB $2, $0, $3", "LW $3, 800($2)", "SUBI $3, $3, 3",
"ADDI $2, $2, 4", "SW $3, 108($2)", "SUB $4, $5, $3"]
codice_1516 = ["SW $3, 80($0)", "ADD $2, $3, $1", "LW $1, 800($2)", "SUBI $1, $1, 3",
"ADDI $2, $2, 4", "SW $1, 108($2)", "SUB $4, $3, $1"]
print(cicli(codice_1415), cicli(codice_1516)) # 17 17Errori comuni
- Contare uno stallo solo per il caso "istruzione immediatamente successiva": con c'è ancora 1 stallo.
- Sommare gli stalli dei due operandi della stessa istruzione (
SW) invece di prendere il massimo. - Dimenticare di ritardare anche le istruzioni successive (la pipeline è in ordine).
- Usare le regole del forwarding quando il testo dice "senza data-forwarding" (e viceversa).
- Dimenticare la possibilità di scrittura e lettura nello stesso ciclo: senza di essa costerebbe 3 stalli.
Versione ripasso
Esempi di compitino a.a. 2014-15 e 2015-16: 7 istruzioni MIPS, pipeline a 5 stadi senza forwarding, scrittura e lettura dei registri nello stesso ciclo. Teoria: PipelineIdea della catena di montaggio; pipeline a 5 stadi IF, ID, EX, MEM, WB; tempo di ciclo, tempo per n istruzioni in una pipeline a k stadi e speedup con esempi svolti; registri di pipeline; scrittura e lettura dei registri nello stesso ciclo; limiti (stadi sbilanciati, hazard).Pipeline →, Hazard nella pipelineHazard strutturali, sui dati e sul controllo; dipendenze RAW, WAR e WAW; stalli e bolle con diagrammi; data forwarding (bypass) e caso load-use; riordino delle istruzioni da parte del compilatore e dell'hardware; costo dei salti.Hazard nella pipeline →.
Regola: il consumatore deve avere l'ID nel ciclo del WB della produttrice o dopo. Stalli per distanza : → 2; → 1; → 0. Con due operandi in dipendenza si prende il massimo. Cicli istruzioni stalli.
Dipendenze del codice 2014-15: LW $3, 800($2) dipende da SUB $2 (, 2 stalli); SUBI $3, $3, 3 da LW $3 (, 2 stalli); ADDI $2 da SUB $2 (, 0); SW $3, 108($2) da SUBI (, 1) e ADDI (, 2) → 2; SUB $4, $5, $3 0. Totale stalli , cicli → opzione d.
2015-16: stessa struttura, 17 cicli, assente tra le opzioni 13/15/19/14 → e.
Errori comuni: stalli solo per ; stalli dei due operandi sommati; istruzioni successive non ritardate; regole del forwarding applicate al caso senza.