Architetture a pipeline
Pipeline: una catena di montaggio Un semplice modello di pipeline ideale Dipendenze (pipeline hazards), Soluzioni Conclusioni: limitazioni della in-order pipeline Architetture superscalari, superpipeline & combinate
Architetture a pipeline
Marko Pali IE 105
Pipeline: una catena di montaggio La tecnica di pipelining è la più vecchia, semplice ed efficace per aumentare le prestazioni di un processore. Il numero di stadi di una pipeline può variare moltissimo a seconda del periodo storico, del costo del processore, e dell’ambito di utilizzo. Il concetto base è semplice: supponiamo di avere un processore single-cycle, ovvero che esegue una e una sola istruzione completa (dal fetch al ritiro) in un ciclo di clock. Evidentemente, c’è un grosso spreco nell’utilizzo della logica. Molto più efficiente sarebbe applicare il principio della catena di montaggio: dopo che una istruzione lascia il fetch, subito cominciare il fetch della prossima, e così via. Per farlo, è necessario “spezzare” il processore in più sezioni indipendenti, che lavorano, nello stesso momento, su istruzioni diverse; le diverse sezioni sono isolate l’una dall’altra tramite buffer. Il ritardo dei buffer si aggiunge al tempo di esecuzione dell’istruzione: il tempo per eseguire la singola istruzione è più alto, ma il throughput del sistema è maggiore, perchè più istruzioni vengono istruite contemporaneamente. Quanti stadi? Suddividere il circuito in più stadi è vantaggioso, ma quanti? Un semplice modello che studia il tradeoff tra costo e performance è quello illustrato in figura. Si parta dal processore senza pipeline, con un ritardo di propagazione T e un costo hardware G. Ogni stadio di pipeline aggiunge dei registri, che hanno un ritardo S e un costo L. Il throughput e il costo del processore pipelined a k stadi è mostrato in figura, cosi’ come il punto ottimo.Il ritardo e il costo dei registri stanno al denominatore, cioè più i registri costano poco, più conviene aggiungere stadi. All’inizio, aggiungendo pochi stadi si ottengono grossi incrementi prestazionali con poco costo. Man mano che si aggiungono stadi, il miglioramento prestazionale diventa via via sempre più piccolo (ormai gli stadi sono così piccoli che il tempo di ritardo è dominato dai registri di pipeline), mentre il costo hardware continua ad aumentare.E’ importante ricordare che questa analisi non tiene conto dell’energia consumata dal processore. Pipeline con molti stadi diventano rapidamente svantaggiose, perchè non è possibile aumentare la frequenza oltre limiti ormai “bassi”
2
Architetture a pipeline
Marko Pali IE 105
Un semplice modello di pipeline ideale Un modello generico è la pipeline a 4 stadi così costruita: (1) F_fetch (caricamento). L'istruzione è caricata nella CPU. (2) D_decode (decodifica). L'istruzione è decodificata e gli operandi vengono eventualmente prelevati dal register file. (3) E_execute (esecuzione). L'istruzione è eseguita. (4) W_writeback (memorizzazione). I risultati dell'esecuzione vengono memorizzati.
Idealmente,
essa
ha
questo
“aspetto”:
Come vedremo, però, questa visione idilliaca è ben lontana dalla realtà. Rimozione delle idealità Fino a questo punto sono state fatte alcune ipotesi implicite sull’idealità della pipeline. Esse sono: o o o
sotto-operazioni uniformi: le operazioni del processore possono essere arbitrariamente suddivise in sottooperazioni di identica durata ripetizione di operazioni identiche: le stesse operazioni vengono ripetute identiche su un grande numero di input diversi ripetizione di operazioni indipendenti: tutte le operazioni, e tutti gli stadi, sono indipendenti tra loro (cioè non esiste alcuna dipendenza tra i dati, e nessuna scarsezza di risorse)
Sfortunatamente, tutte queste ipotesi sono false: o
o
o
le sotto-operazioni non sono uniformi: non è possibile “tagliare” i circuiti in punti arbitrari, ma solo ai confini delle unità funzionali, al massimo, delle porte logiche; è necessario far sì che i diversi stadi siano il più simili possibile, per evitare che gli stadi più veloci sprechino tempo per aspettare quelli più lenti . le operazioni non sono identiche: una ISA ha nell’ordine delle centinaia di diverse istruzioni; costruire una pipeline “multifunzionale” capace di eseguirle tutte vuol dire avere degli stadi dedicati a certe istruzioni, che dovranno essere attraversati (inutilmente) da altre istruzioni che non ne fanno uso; è necessario minimizzare il numero di questi stadi le operazioni non sono indipendenti: il più delle volte un’istruzione dipende dal risultato di una precedente, è fondamentale scoprire e risolvere tutte queste dipendenze, pena l’esecuzione errata del programma 3
Architetture a pipeline
Marko Pali IE 105
I primi due punti riguardano le prestazioni della pipeline. Rendere le sotto-operazioni il più uniforme possibile (dal punto di vista temporale) significa poter spingere il clock fino al limite massimo. Inoltre, minimizzare gli stadi “idle” per certe istruzioni significa rendere disponibili prima i loro risultati, risultati che saranno utilizzati dalle istruzioni successive. Ma il terzo punto ci dice qualcosa di diverso: se non teniamo conto delle dipendenze tra le istruzioni, il programma non sarà lento, ma sbagliato! Il problema è che l’ISA ci dice di assumere che una e una sola istruzione sia in esecuzione in un dato istante, e che ogni istruzione deve essere completata prima che l’istruzione successiva cominci l’esecuzione. In una pipeline, questo non è vero: per accelerare, cominciamo ad eseguire l’istruzione i+1 quando l’istruzione i non ha ancora finito. Se non ne teniamo conto, l’istruzione i+1 accederà ai dati sbagliati, lo stato della macchina verrà distrutto, e il programma fallirà.
Dipendenze( pipeline hazards) , Soluzioni Nella maggior parte dei casi, una istruzione “dipende” da una o più istruzioni precedenti, nel senso che queste istruzioni precedenti devono aver completato prima che la nuova istruzione possa eseguire. Di quali dipendenze bisogna preoccuparsi, allora, quando si costruisce una pipeline? Ce ne sono di tre tipi: 1. Dipendenze strutturali (Hazard strutturali). Derivano dai conflitti di risorse, quando l'hardware non può supportare tutte le possibili combinazioni di istruzioni, simultaneamente sovrapposte nei diversipipeline stage durante la loro esecuzione.
Soluzione Gli effetti degli hazard strutturali possono essere evitati replicando le risorse. Per esempio, se abbiamo una doppia cache, una per il codice e una per i dati, con separati bus di accesso e registro di indirizzamento di memoria, la CPU può accedere alla cache di codice allo stage F di un'istruzione, e simultaneamente può accedere alla cache dei dati nello stadio E di un'altra istruzione. Usando molteplici bus interni con un register file multiporta si possono alleviare molti dei problemi dell'uso simultaneo dei bus interni e del simultaneo accesso ai registri da parte di istruzioni differenti in differenti stadi della pipe. Queste caratteristiche sono indispensabili nel progetto dei moderni microprocessori. Un altro problema che potrebbe sorgere è dovuto alla necessità di incrementare il PC (Program Counter) dopo aver caricato l'istruzione. Si crea un conflitto con l'istruzione allo stage E (Esecuzione) nella sequenza. Per questo motivo la maggioranza dei sistemi adotta un circuito logico dedicato esclusivamente all' incremento del contatore di programma. 2. Dipendenze sui controlli (Hazard sui controlli). Derivano dalla presenza di salti e altre istruzioni di controllo che cambiano il flusso di istruzioni nel pipeline. Quando un'istruzione di salto dentro la pipe giunge nello stadio di esecuzione E e viene accettata (perchè il salto è incondizionato o il salto condizionato è riconosciuto valido), le istruzioni successive non devono essere elaborate. Queste però hanno già riempito la sequenza degli stadi precedenti ad E, ma poiché il flusso del programma si dirama in un'altra direzione, questi stadi devono essere rimossi. Soluzione Al fine di minimizzare gli effetti deglihazard sui controlli si seguono i seguenti punti :
4
Architetture a pipeline
Marko Pali IE 105
Riconoscere i salti il più ``presto'' possibile nella pipe. Se un salto è di tipo incondizionato, cioè viene comunque eseguito, il riconoscimento è realizzabile semplicemente nello stage D. Per un salto di tipo condizionato è più difficile, poiché una condizione deve essere testata dopo che l'istruzione è decodificata e questo richiede un tempo maggiore. Individuare l'indirizzo di salto e caricarlo nel PC il più ``presto'' possibile. Se l'indirizzo deve essere calcolato seguendo un qualche metodo di indirizzamento, sarà richiesto un ciclo aggiuntivo
3. Dipendenze sui dati (Hazard sui dati). Quando un'istruzione dipende dai risultati di una precedente istruzione parzialmente sovrapposta nella pipe.
Soluzione (a) La tecnica di stallo della pipe (pipeline interlocking) Il modo migliore per rimediare a questo inconveniente è stallare la pipe di due cicli. Aumentando il numero di stadi di esecuzione dell'istruzione successiva attraverso due stadi non necessari al completamento dell'istruzione in sè, si attende infatti che il risultato della somma venga scritto in r1 al quarto ciclo, per poterlo leggere correttamente. Questi due stadi aggiuntivi sono detti stadi di stallo della pipe, in quanto solitamente non prevedono un'operazione utile all'esecuzione del programma. Questa tecnica è molto semplice anche se produce la perdita di due cicli utili. Quando viene rilevato un pipeline hazard e delle fasi di stallo vengono introdotte dal sistema, il meccanismo prende il nome dipipeline interlock. Nei primi microprocessori della famiglia MIPS, veniva realizzato in modo software ma nei processori moderni invece è un dispositivo hardware che blocca la pipe con degli stalli o ``bolle'' (b) La tecnica forwarding Esiste una tecnica più sofisticata, che richiede però una complicazione dell'unità operativa. Non tutti i tipi di data hazard possono essere risolti attaverso il forwarding. Infatti le istruzioni registro-registro, che coinvolgono cioè dei registri e la cui destinazione è ancora un registro, sono eseguite interamente durante un ciclo. Non è sicuramente il caso di un'istruzione di accesso alla memoria. Anche se il dato è prelevato da una memoria cache on chip, bisogna utilizzare un ciclo per calcolare l'effettivo indirizzo e completare la traslazione dall'indirizzo virtuale all'indirizzo fisico, e un ciclo per accedere alla memoria cache, prelevare il dato e memorizzarlo nel registro destinazione. Il risultato di un'istruzione di caricamento dati non è disponibile alla fine dello stage E, quindi nessuna tecnica di forwarding può essere adottata. (c) Schedulazione statica del compilatore Molti compilatori moderni usano la schedulazione per incrementare le prestazioni del pipeline. Sostanzialmente, nella fase di generazione del codice macchina, esso si occupa di produrre delle sequenze di istruzioni che riducano le dipendenze della pipe. Gli algoritmi più semplici definiscono dei ``blocchi base'' all'interno dei quali il codice non produce letture o scritture in memoria, ad eccezione dell'inizio e della fine del blocco. Il compilatore a questo punto si costruisce un grafo delle dipendenze e le minimizza.
5
Architetture a pipeline
Marko Pali IE 105
Conclusioni: limitazioni della in-order pipeline Il pipelining è una tecnica relativamente semplice ed estremamente efficace per aumentare le prestazioni dei processori. È la tecnica che ha permesso alle CPU di aumentare la frequenza operativa in modo esponenziale. Tuttavia, la semplice pipeline in-order soffre di alcune grosse limitazioni: o o
o
o
ha un limite fisiologico di IPC (istruzioni per clock) pari a 1: come ovvio, al più una istruzione può entrare, e una uscire, dalla pipeline ad ogni colpo di clock pipeline molto lunghe sono inefficienti: all’aumentare del numero di stadi il guadagno di frequenza diminuisce sempre di più, l’overhead di area aumenta, la dissipazione termica diventa ingestibile, e le dipendenze introducono sempre più stalli nella pipeline; la maggior parte dei processori si è assestata su pipeline tra 10 e 20 stadi rigidità: se un’istruzione stalla, tutte quelle che seguono devono per forza stallare, e l’intera pipeline si ferma; questo non è strettamente necessario: alcune istruzioni potrebbero continuare a procedere, se non hanno dipendenze con quelle che vengono prima di loro, ma la pipeline in-order non lo permette inefficienza di unificazione: creare una singola pipeline capace di eseguire ogni tipo di istruzione significa necessariamente introdurre stadi dedicati ad alcune operazioni (e quindi inutili per tutte le altre); questo incrementa la latenza di esecuzione delle singole istruzioni, e aumenta il numero di dipendenze e il numero di stalli che devono essere introdotti.
Architetture superscalari e architetture superpipeline Si definisce processore superscalare una macchina che può caricare più di istruzione per ciclo di clock. Si definisce processore superpipeline invece una macchina che può caricare una sola istruzione per ciclo di clock ma che abbia cicli di clock più piccoli della latenza di una qualsiasi delle unità funzionali. In una macchina pipeline, sebbene le istruzioni vengano eseguite in concorrenza, in ciascuno stage della pipe è presente un sola istruzione. In particolare anche nello stadio di E (esecuzione) è istanziata una sola operazione. In una macchina superscalare di grado n , il numero di istruzioni attive nel stadio E (ma anche negli altri stadi) è n. Per sfruttare completamente questa ``pipereplicata'', devono esserci n istruzioni eseguibili in parallelo (grado di ILP = n), altrimenti si dovranno forzare degli stalli ad attendere i dati provenienti dalle precedenti istruzioni. Formalizzando, avremo dunque:
Istruzioni caricate per ciclo = n 6
Architetture a pipeline
Marko Pali IE 105
Latenza di ciascuno stadio della pipe = 1 ILP necessario = n
Molti microprocessori realizzano questa tecnologia, con livelli di parallelismo due, tre , quattro oppure, come nel caso del multichip IBM POWER2, con livello sei. Una macchina supepipeline sfrutta l'ILP in un altro modo. In un'architettura superpipeline di grado m, il ciclo di clock è 1/m (il ciclo di clock della macchina di base), cioè la macchina pipeline. Si ridefinisce sostanzialmente il periodo del segnale di cadenza negli stadi della catena. Ad esempio, una somma che occupava un ciclo unico della macchina pipeline nello stage E, richiederà ora m cicli per completare lo stage della pipe. Si noti come le m istruzioni che vengono ora a trovarsi nello stadio (come per l'architettura superscalare) siano però caricate in m cicli di clock successivi. Formalizzando in un schema le caratteristiche esposte avremo:
Istruzioni caricate per ciclo = 1 (ma il ciclo di clock è 1/m la macchina di base) Latenza di ciascuno stadio della pipe = m ILP necessario = m
Gli unici microprocessori superpipeline commercializzati finora sono il MIPS R4000 e il MIPS R4400. Architetture superscalari superpipeline Poiché il numero di istruzioni caricate in un ciclo di clock e la latenza di uno stadio della pipe sono ortogonali, possiamo combinare le due precedenti architetture in un'unica macchina di grado (m,n) che abbia un ciclo di clock pari a 1/m della macchina di base e che possa eseguire n istruzioni per ciclo. In questo caso avremo dunque: Istruzioni caricate per ciclo = n (il ciclo di clock è 1/m la macchina di base) Latenza di ciascuno stadio della pipe = m ILP necessario = m * n
Referenze Progetto e validazione di una CPU in pipeline. /UNIVERSITA DEGLI STUDI DI FIRENZE Facolta di Ingegneria - Dipartimento di Sistemi e Informatica APPUNTI DI INFORMATICA/ Le architetture pipeline di Giuseppe Cardinale Ciccotti
7