Le architetture a pipeline M. Sonza Reorda Politecnico di Torino Dip. Automatica e Informatica
1
Introduzione Per migliorare le prestazioni di un processore si può agire in due direzioni: • aumentando la velocità dei componenti • modificando l’architettura. L’uso di architetture a pipeline segue la seconda strada.
2
Processori RISC e superscalari I processori tradizionali richiedono un certo numero di colpi di clock per l’esecuzione di ogni istruzione. Grazie all’introduzione delle pipeline, in ogni colpo di clock • i processori RISC possono completare un’istruzione • i processori superscalari possono completare anche più di un’istruzione.
3
CPI Per misurare l’efficienza di un processore si usa a volte il parametro CPI (Clocks per Instruction): • per processori CISC ⇒ CPI > 1 • per processori RISC ⇒ CPI ~ 1 • per processori superscalari ⇒ CPI < 1.
4
Pipeline La pipeline è l’equivalente elettronico della catena di montaggio. Permette di eseguire in parallelo operazioni diverse sullo stesso flusso di dati.
Dati Unità 1
5
Unità 2
Unità 3
Pipeline ideale Se • tutti i dati devono passare attraverso gli stessi stadi • tutti gli stadi richiedono sempre lo stesso tempo per eseguire la relativa elaborazione allora l’uso di una pipeline di n stadi può portare a regime ad un miglioramento di n volte nelle prestazioni.
6
La pipeline nei processori L’esecuzione di ciascuna istruzione può essere suddivisa in varie fasi, quali: • Fetch (o prelievo): caricamento dell’istruzione dalla memoria • Decode (o decodifica): decodifica dell’istruzione e lettura degli operandi sorgente • Operate (o elaborazione): esecuzione dell’operazione • Write (o scrittura): scrittura del risultato. Ciascun processore può adottare una suddivisione in un numero di fasi diverso: • Processori ARM: 3 fasi • Processori Intel Netburst (Pentium 4): 31 fasi. 7
Stadio della pipeline in ogni periodo di clock esegue una fase su un’istruzione
O
R3
D
R2
R1
F
Architettura
Registri di pipeline sincronizzati con lo stesso clock 8
W
Esempio Colpo di clock Istruzione
i
I1
F
I2 I3 I4 I5 9
i+1 i+2 i+3 i+4 i+5 i+6 i+7 D
O
W
F
D
O
W
F
D
O
W
F
D
O
W
F
D
O
W
Esempio Colpo di clock Istruzione
i
I1
F
I2
i+1 i+2 i+3 i+4 i+5 i+6 i+7 D
O
W
F
D
O
W
F
D
O
W
F
D
O
W
F
D
O
I3 I4 I5 10
Ad ogni colpo di clock viene terminata l'esecuzione di un'istruzione.
W
Stallo
11
In un processore reale, è possibile che a volte uno stadio non riesca a completare il proprio compito in un colpo di clock. In tal caso • gli altri stadi a monte devono arrestarsi, ossia andare in stallo, in quanto i registri in cui devono scrivere non sono liberi • gli stadi a valle possono invece continuare a lavorare, ma solo per smaltire le istruzioni già processate dallo stadio critico. In tal modo le prestazioni del processore scendono rispetto a quelle ideali previste.
Cause di stallo • Lentezza negli accessi a memoria (fasi F, D e W) • Lentezza nell’esecuzione di operazioni interne (fase O).
12
Esempio Colpo di clock Istruzione
i
I1
F
I2
i+1 i+2 i+3 i+4 i+5 i+6 i+7 D
O
W
F
D
O
F
D
O
W
F
D
O
W
F
D
O
I3 I4 I5 13
L’istruzione I2 richiede 2 colpi di clock per completare la fase di Operate.
O
W
W
Cache Le cache sono fondamentali nei processori che usano una pipeline, in quanto permettono di accedere a dati e istruzioni in un solo colpo di clock.
14
Bolle Dopo che uno stadio è andato in stallo, si crea all’interno della pipeline una situazione di inattività (denominata bolla) che viene eliminata gradualmente.
15
Coda delle istruzioni Quando l’unità di fetch non trova un’istruzione in cache, manda in stallo l’intera pipeline. Per evitare questa situazione, il buffer tra le unità di fetch e di decodifica è sostituito da una coda, detta coda delle istruzioni. L’unità di fetch cerca di mantenere sempre piena tale coda, caricando anche più di un’istruzione per colpo di clock. In tal modo si compensano eventuali ritardi dovuti a situazioni di miss nella cache. 16
Architettura
O
Coda delle istruzioni Registri di pipeline 17
R3
D
R2
R1 R1 R1
F
W
Dipendenze di dato La presenza di una pipeline rende parallelo un processo (quello di esecuzione delle istruzioni) che è originariamente sequenziale. Affinché il risultato sia lo stesso del processo originario, bisogna che non vi siano dipendenze tra dati. Ad esempio bisogna che gli operandi sorgente di un’istruzione siano già stati prodotti dalle istruzioni precedenti.
18
L’istruzione MUL carica in R4 il valore del risultato in questo colpo di clock
Esempio Mul Add
Periodo di clock 1 Istruzione
2
3
4
Mul
D
O
W
F
D
O
W
F
D
O
W
F
D
O
Add I3
19
R2, R3, R4 R5, R4, R6
I4
F
5
6
7
W
8
L’istruzione MUL carica in R4 il valore del risultato in questo colpo di clock
Esempio Mul Add
Periodo di clock 1 Istruzione
2
Mul
D
O
W
F
D F
Add I3
20
R2, R3, R4 R5, R4, R6
I4
F
3
4
5
6
7
O
W
L’istruzione ADD legge da R4 il valore dell’operando in questo colpo di clock
D
O
W
F
D
O
W
8
L’istruzione MUL carica in R4 il valore del risultato in questo colpo di clock
Esempio Mul Add
R2, R3, R4 R5, R4, R6
Periodo di clock 1 Conclusione 2 3 4 5 6 7 8 Istruzione L’istruzione È necessario garantire la correttezza del risultato. ADD legge da R4 il valore MulQuesto può essere F fatto D O W dell’operando in • in HW questo colpo di • in SW. Add F D O W clock I3
21
I4
F
D
O
W
F
D
O
W
Soluzione HW L’HW della pipeline è in grado di – riconoscere le situazioni di dipendenza dei dati – inibire il funzionamento di specifici moduli della pipeline (introducendo degli stalli) per garantire la correttezza del risultato.
22
Esempio Mul Add
Periodo di clock 1 Istruzione
2
3
4
Mul
D
O
W
Add I3
23
R2, R3, R4 R5, R4, R6
I4
F
F
5
6
7
8
D
O
W
F
D
O
W
F
D
O
W
La fase di Decode non può Esempio
Periodo di clock 1 Istruzione
2
3
essere eseguita sino a che non è stata eseguita la fase di Write dell'istruzione precedente, che produce il 4 valore 5 aggiornato 6 7 8di R4.
Mul
D
O
W
Mul Add
Add I3
24
I4
R2, R3, R4 R5, R4, R6
F
F
D
O
W
F
D
O
W
F
D
O
W
Soluzione SW Il compilatore introduce delle istruzioni NOP, che permettono alla pipeline di produrre un risultato corretto. Esempio Codice originale Ii Mul R2, R3, R4 Add R5, R4, R6 Ij Ik … 25
codice modificato Ii Mul R2, R3, R4 NOP Nop Add R5, R4, R6 Ij
Esempio Mul Nop Nop Add
R5, R4, R6
Periodo di clock 1 Istruzione
2
3
4
Mul
D
O
W
F
D
O
W
F
D
O
W
F
D
O
Nop Nop
26
R2, R3, R4
Add
F
5
6
7
W
8
Istruzioni di salto Le istruzioni di salto sono potenzialmente molto dannose per le prestazioni della pipeline, in quanto interrompono il normale flusso di esecuzione sequenziale.
27
lab:
Esempio
Ii JMP lab Ih Ij Ik
Periodo di clock 1 Istruzione Ii JMP lab Ih
28
Ij
L’istruzione JMP carica nel PC il nuovo valore in questo colpo di clock
F
2
3
4
D
O
W
F
D
O
W
F
D
O
W
F
D
O
5
6
7
W
8
lab:
Esempio
Ii JMP lab Ih Ij Ik
Periodo di clock 1 Istruzione Ii JMP lab Ih
29
Ij
L’istruzione JMP carica nel PC il nuovo valore in questo colpo di clock
F
2
3
4
D
O
W
F
D
O
W
F
D
O
W
F
D
O
5
6 L’unità 7 8 di fetch carica dalla memoria l’istruzione Ih anziché Ik
W
lab:
Esempio
Ii JMP lab Ih Ij Ik
Periodo di clock 1 Istruzione Ii JMP lab
30
L’istruzione JMP carica nel PC il nuovo valore in questo colpo di clock
F
2
3
4
D
O
W
F
D
O
W
F
D
O
W
F
D
O
L’unità di fetch Ih carica l’istruzione I j che non doveva essere eseguita Ij
5
6 L’unità 7 8 di fetch carica dalla memoria l’istruzione Ij anziché Ih
W
Intervallo di ritardo del salto Viene denominato intervallo di ritardo del salto (branch delay slot) il numero di colpi di clock successivi ad un’istruzione di salto, nei quali il processore esegue il fetch usando un valore del PC che non è necessariamente corretto.
31
Soluzioni Per garantire la correttezza dei risultati prodotti dal processore anche in presenza di salti si possono anche qui utilizzare • tecniche HW • tecniche SW.
32
Tecniche HW Possono • rilevare le istruzioni di salto, e svuotare conseguentemente la pipeline dalle istruzioni erroneamente caricate oppure • implementare tecniche più sofisticate, che dipendono dal fatto che il salto sia incondizionato o condizionato.
33
lab:
Esempio
Ii JMP lab Ih Ij Ik
Periodo di clock 1 Istruzione Ii JMP lab Ih Ik 34
…
La CPU a questo istante capisce che l’istruzione corrente è di salto condizionato e interrompe i fetch, inserendo stalli 4 5 6 7 8 A questo istante viene caricato il W nuovo valore di PC e riparte il fetch O W
F
2
3
D
O
F
D F
F
D
O
W
F
D
O
W
Tecniche SW Sono basate su • Salto ritardato introduzione di istruzioni NOP da parte del compilatore (dopo ogni salto si inseriscono tante NOP quanto è il branch delay slot) oppure • un’ottimizzazione del codice.
35
Soluzione SW
36
Il compilatore introduce delle istruzioni NOP, che permettono alla pipeline di produrre un risultato corretto. Esempio Codice originale codice modificato Ia Ia Ib Ib Ic Ic Id Id JMP lab_1 JMP lab_1 Ij NOP Lab_1: Ik NOP NOP Ij Lab_1: Ik
Inserimento di Nop Id JMP Nop Nop Nop
37
Ik
F
In questo colpo di clock l’istruzione JMP carica nel PC il nuovo valore, corrispondente all’indirizzo di Ik
D
O
W
F
D
O
W
F
D
O
W
F
D
O
W
F
D
O
W
F
D
O
W
Ottimizzazione L’istruzione di salto viene anticipata ed eseguita prima di un numero istruzioni (se possibile) pari al branch delay slot, in modo da non far eseguire al processore le istruzioni NOP. Ia JMP Ib Ic Id 38
Ik
F
D
O
W
F
D
O
W
F
D
O
W
F
D
O
W
F
D
O
W
F
D
O
W
Salti condizionati In questo caso è necessario attendere l’esecuzione dell’istruzione precedente a quella di salto per sapere se il salto deve essere eseguito o meno. Nel frattempo però la coda delle istruzioni è stata riempita sequenzialmente. Se il salto viene eseguito, vi saranno alcune istruzioni provenienti dalla coda che non dovranno essere eseguite (tante quante la dimensione del branch delay slot).
39
Predizione di salto Se si usa una tecnica HW, la predizione permette di ridurre la penalizzazione introdotta da un’istruzione di salto. Consiste nel far sì che l’unità di fetch disponga di una previsione sul fatto che il salto venga effettuato o meno. Se la previsione è affermativa, essa carica le istruzioni a partire da quella destinazione; se è negativa, continua a caricare le istruzioni successive a quella di salto. Successivamente, si verificherà se la previsione era corretta; in caso negativo si deve svuotare la pipeline.
40
I processori RISC A partire dali primi anni ‘80 furono progettati e poi realizzati alcuni processori caratterizzati da • Elevata semplicità • Numero ridotto di istruzioni (da cui la sigla RISC, che sta per Reduced Instruction Set Computer) • Elevato numero di registri • Architettura a pipeline. Negli anni ‘90 esistevano sul mercato varie famiglie di processori RISC, tra cui • ARM • SPARC (Sun) • MIPS • PowerPC (IBM). 41
Caratteristiche dei RISC: 1 istruzione = 1 colpo di clock
42
Ogni istruzione corrisponde a varie operazioni: • fetch degli operandi dai registri • attivazione della ALU • memorizzazione del risultato in un registro. Grazie all’adozione della pipeline, è possibile sovrapporre temporalmente l’esecuzione di più istruzioni, in modo che ad ogni colpo di clock si termini normalmente l’esecuzione di una istruzione. Per poter utilizzare al meglio la pipeline è necessario che le istruzioni siano • Semplici • Regolari (formato fisso).
Caratteristiche dei RISC: unità di controllo Le istruzioni RISC hanno la complessità delle microistruzioni CISC; per questa ragione l’unità di controllo dei RISC può essere realizzata con la tecnica cablata, anziché microprogrammata.
43
Caratteristiche dei RISC: LOAD & STORE I processori RISC hanno normalmente due sole istruzioni che coinvolgono la memoria • LOAD (memoria ⇒ registro) • STORE (registro ⇒ memoria). Questo permette di concentrare su 2 sole istruzioni gli sforzi per ridurre l’impatto negativo legato al calcolo dell’indirizzo e all’accesso in memoria. Tali istruzioni sono le uniche a prevedere dei meccanismi per specificare l’indirizzo a cui accedere in memoria (modi di indirizzamento). 44
Caratteristiche dei RISC: formato delle istruzioni I RISC hanno un formato delle istruzioni fisso o con poche alternative: il codice operativo ha di solito una lunghezza fissa. Ne conseguono alcuni vantaggi: • la decodifica del codice operativo può avvenire in parallelo con il caricamento degli operandi dai registri • l’unità di controllo è più semplice • la fase di fetch è più ottimizzata.
45
Caratteristiche dei RISC: modi di indirizzamento I RISC possiedono un numero limitato di modi di indirizzamento, che comunque vengono utilizzati solo nelle istruzioni LOAD e STORE.
46
I registri I registri sono la forma di memoria con minore tempo di accesso in quanto: • risiedono sullo stesso chip della CPU • sono costruiti con la tecnologia più veloce • sono accessibili con un meccanismo di indirizzamento semplice. Si può guadagnare in efficienza di esecuzione in 2 modi: • aumentando il numero di registri • ottimizzando il loro uso. I registri sostituiscono lo stack (ad es. per la memorizzazione dei parametri per le procedure, delle variabili locali e dell’indirizzo di ritorno), riducendo il numero di accessi nello stack (ossia memoria). 47
Dimensione del codice eseguibile • I compilatori per RISC sono più complessi di quelli per i CISC (pur producendo codice composto da istruzioni più semplici) in quanto devono ottimizzare il codice per evitare gli stalli • Il codice generato per un RISC ha dimensioni comparabili con quelle per un CISC in quanto: • il numero di istruzioni RISC generate è maggiore, ma • ogni istruzione occupa un numero inferiore di byte • Codici più corti sono più efficienti perché: • si riduce il numero di fetch • si riduce il numero di page fault. 48
Conclusioni sull’approccio RISC • Le istruzioni CISC, per quanto più complesse, non sono più veloci, in quanto richiedono un hardware più complicato • La gestione ottimizzata della pipeline delle istruzioni è più semplice con i RISC • La disponibilità di un elevato numero di registri permette di ridurre significativamente il numero di accessi in memoria • Nei RISC il tempo medio di attesa per il servizio di un interrupt (latenza) è inferiore rispetto ai CISC.
49
I processori superscalari I processori superscalari possono completare l’esecuzione di più di un’istruzione per ciascun colpo di clock. Internamente, contengono una pipeline in cui a ciascuno stadio corrisponde più di una unità.
50
Comportamento ideale Periodo di clock 1
51
2
3
4
5
6
7
F
D
O
W
F
D
O
W
F
D
O
W
F
D
O
W
F
D
O
W
F
D
O
W
F
D
O
W
F
D
O
W
Esempio Unità aritm. virgola mobile
Coda delle istruzioni
52
D
R3
…
R2
R1
R1
F
Unità aritm. intera
W
L’unità di fetch può caricare 4 istruzioni per colpo di clock
Esempio Unità aritm. virgola mobile
Coda delle istruzioni
53
D
R3
…
R2
R1
R1
F
Unità aritm. intera
W
L’unità di decodifica può decodificare 2 istruzioni per colpo di clock e, se sono adatte, smistarle alle due unità aritmetiche dopo aver caricato Unità i relativi operandi.
Esempio
aritm. virgola mobile
Coda delle istruzioni
54
D
R3
…
R2
R1
R1
F
Unità aritm. intera
W
Esempio Unità aritm. virgola mobile
D
Coda delle istruzioni L’unità per l’aritmetica in virgola mobile richiede 3 colpi di clock 55
R3
…
R2
R1
R1
F
Unità aritm. intera
W
L’unità per l’aritmetica in virgola mobile richiede 1 colpo di clock
Esempio Unità aritm. virgola mobile
Coda delle istruzioni
56
D
R3
…
R2
R1
R1
F
Unità aritm. intera
W
Flusso di esecuzione
57
Periodo di clock 1 Istruzione
2
3
4
5
I1 (Fadd)
F
D
O
O
O W
I2 (Add)
F
D
O W
I3 (Fsub)
F
D
O
I4 (Sub)
F
D
O W
O
6
7
O W
8
Note • Le unità appartenenti allo stesso stadio possono anche essere funzionalmente uguali • La gestione della pipeline deve garantire la correttezza delle operazioni svolte, tenendo conto delle dipendenze tra dati • L’esempio riporta un caso di completamento non-inordine delle istruzioni.
58
Esempio: Intel Pentium Processore Intel, della famiglia x86, prodotto dal 1993: • possedeva 2 pipeline che gli permettevano di completare più di una operazione per ciclo di clock: • "pipeline U" poteva eseguire qualunque istruzione, • "pipeline V" era in grado di eseguire solo quelle più semplici e comuni (logica cablata).
PF
59
D2
E
WB
U pipe
D2
E
WB
V pipe
D1
Architettura del PowerPC 603 Bus di memoria Cache dati
Cache istruz.
Unità di prelievo
Unità di salto
Coda delle istruzioni
Unità di smistamento
LSU
FPU IU
60
Coda di memorizzaz.
Coda di completamento
SRU
Pipeline del PowerPC 603 Bus di memoria Cache dati
Cache istruz.
Unità di prelievo
Unità di salto
Coda delle istruzioni
Estrae due istruzioni per colpo di clock dalla cache. Invia le istruzioni di salto direttamente all’unità di salto. Invia le altre istruzioni alla LSU ne coda delle istruzioni, che può contenere sino a 6.
61
Coda di memorizzaz.
Unità di smistamento
FPU IU
Coda di completamento
SRU
Pipeline del PowerPC 603 Bus di memoria Cache dati
Cache istruz.
Unità di prelievo
Unità di salto
Coda delle istruzioni
Unità di smistamento
LSU
Implementa la tecnica di predizione statica. FPU IU
62
Coda di memorizzaz.
Coda di completamento
SRU
Pipeline del PowerPC 603 Bus di memoria Cache dati
Smista all’opportuna unità di Operate fino a due istruzioni per colpo di clock. Un’istruzione viene smistata solo quando tutte le risorse di cui ha bisogno sono disponibili.
Cache istruz.
Unità di prelievo
Coda delle istruzioni
Unità di smistamento
LSU
FPU IU
63
Coda di memorizzaz.
Unità di salto
Coda di completamento
SRU
Pipeline del PowerPC 603 Bus di memoria Cache dati
Cache istruz.
Unità load/store: richiede due colpi di clock. Unità di Il primo calcola l’indirizzo, prelievo il secondo accede in memoria. Nel Coda caso di miss delle istruzioni nella cache, il dato viene inviato nella coda di Unità di memorizzazione. smistamento LSU
FPU IU
64
Coda di memorizzaz.
Unità di salto
Coda di completamento
SRU
Pipeline del PowerPC 603 Bus di memoria Cache dati
Cache istruz.
Unità di prelievo
Unità di salto
Unità per l’aritmetica intera. Coda delle istruzioni Richiede un solo colpo di clock. Unità di smistamento
LSU
FPU IU
65
Coda di memorizzaz.
Coda di completamento
SRU
Pipeline del PowerPC 603 Bus di memoria Cache dati
Cache istruz.
Unità di prelievo
Unità di salto
Unità per l’aritmetica in Coda delle istruzioni virgola mobile. Richiede 3 colpi di clock. Unità di smistamento
LSU
FPU IU
66
Coda di memorizzaz.
Coda di completamento
SRU
Pipeline del PowerPC 603 Bus di memoria Cache dati
Cache istruz.
Unità di prelievo
Unità di salto
Coda delle istruzioni Unità dei registri di sistema. Richiede un solo colpo di clock. Unità di smistamento
LSU
FPU IU
67
Coda di memorizzaz.
Coda di completamento
SRU
Pipeline del PowerPC 603 Garantisce che le istruzioni Bus di memoria
Cache dati
68
vengano completate in ordine. Cache istruz.inserita Ciascuna istruzione viene nella coda all’atto dello smistamento. Unità di Unità di prelievo Quando un’istruzione esce dallasalto coda, i relativi risultati, che erano delle istruzioni sono scritti in registriCoda temporanei, copiati in quelli definitivi. I relativi registri temporanei Unità di smistamento tornano così liberi. Ad ogni colpo di clock possono venir completate sino a due LSU FPU istruzioni.IU SRU
Coda di memorizzaz.
Coda di completamento
Numero di stadi della pipeline Se cresce, permette teoricamente di aumentare le prestazioni del processore. Ma crescendo il numero di stadi, cresce la probabilità di dipendenze, e quindi che la pipeline debba andare in stallo.
69
Instruction Level Parallelism I processori con pipeline sfruttano il fatto che le istruzioni di un programma possono in molti casi essere eseguite in parziale sovrapposizione (Instruction Level Parallelism, o ILP). Le architetture dei processori superscalari sono in grado di sfruttare al meglio tale forma di parallelismo.
70
Ogni rettangolo nero rappresenta un’istruzione terminata nell’unità di tempo
ILP
Processori multithread Per ottenere ulteriori incrementi di prestazioni è necessario individuare e sfruttare forme diverse di parallelismo, in particolare quello a livello di thread (Thread Level Parallelism, o TLP). Un thread corrisponde ad una porzione di programma con i suoi dati e un programma può essere partizionato su più thread. I processori multithread (Simultaneous Multi-Threading, SMT) eseguono in parallelo più thread. 71
Ogni colore (trannne il bianco) rappresenta un thread
SMT
Processori multicore Un’altra tendenza degli ultimi anni è quella ad integrare nello stesso dispositivo più processori. Ciascun processore ha una complessità non troppo elevata, ed è in grado di eseguire più thread. In tal modo (se si riescono a sfruttare tutti i core) si ottengono prestazioni elevate con bassi consumi.
72
Esempio: Intel Sandy Bridge L’architettura Intel Sandy Bridge fu sviluppata a partire dal 2005. Il primo prodotto basato su quest’architettura fu commercializzato a partire dal 2011. L’architettura permette di combinare fino a 8 core. Altre caratteristiche dell’architettura: • Cache L1: 32 kB data + 32 kB instruction per core • Cache L2: 256 kB per core • Cache L3 cache condivisa (fino a 20MB). 73
Esempio: ARM Cortex-A9 ARM produce IP core di processori per applicazioni embedded. Il Cortex-A9 può essere utilizzato da solo o in configurazione multicore. Rappresenta una soluzione per applicazioni in cui sono richieste alte prestazioni e basso consumo.
74