Nei moderni processori la pipeline riveste un ruolo molto importante. Essa è usata per poter eseguire operazioni di calcolo in parallelo da parte di un processore (sia esso grafico, general purpose o DSP). In pratica, c'è bisogno di avere un certo numero di registri in più integrati nel processore rispetto ad una architettura senza pipeline (quindi più memoria interna). Questo maggior dispendio di risorse è giustificato da una maggiore velocità nell'esecuzione di operazioni ripetitive. Faccio un esempio: se un processore deve effettuare 10 moltiplicazioni e ogni moltiplicazione richiede 10 colpi di clock avrò bisogno di 100 colpi di clock per terminare il processo. Inserendo una pipeline a 10 livelli (nella pratica si arriva a 4-5 livelli ma qui vogliamo semplificare i conti) avremo bisogno di 10 colpi di clock per caricare la pipeline, poi ogni colpo di clock tireremo fuori un risultato della moltiplicazione; il tutto sarà allora eseguito con soli 20 colpi di clock!!!
Per poter eseguire una istruzione, una CPU, deve compiere prima delle operazioni. Vediamo quale è l'iter generale per poter arrivare ad un risultato partendo dai dati e le istruzioni che si trovano in memoria. Per rendere le cose più facili partiamo da un esempio.
Supponiamo di voler calcolare la seguente espressione: 3*4=12.
La prima cosa da capire è che in un processo le operazioni sono sequenziali. Quale sarà la prossima istruzione da eseguire ce lo dice il Program Counter (PC). In questo registro è sempre memorizzato l'indirizzo di memoria della prossima istruzione da eseguire. Allora, nel nostro esempio, supponiamo che il PC contenga l'indirizzo della operazione di moltiplicazione e dei dati 3 e 4. Questo indirizzo viene mandato alla CPU che deve compiere le seguenti operzioni prima di arrivare al risultato:
Reperimento dell'istruzione (attraverso l'indirizzo);
Decodifica dell'istruzione (la CPU deve capire di che istruzione si tratta: booleana come AND, OR, NOT, ... oppure aritmetica come MOLTIPLICAZIONE, SOMMA, ... oppure altre di controllo, ecc.);
Esecuzione dell'istruzione, quindi reperimento dei dati in memoria (3 e 4) e salvataggio del risultato in memoria (12);
Come detto abbiamo bisogno, innanzi tutto, di un certo numero di registri in più. Ma questo non basta: infatti anche il numero di bus di comunicazione deve essere aumentato per far in modo di eseguire più operazioni contemporaneamente sulla memoria. Con una pipeline a regime di 3 livelli siamo in grado di eseguire una operazione ogni ciclo di clock. Guardiamo la figura seguente:
Il blocco Rep è quello che si occupa del reperimento dell'istruzione, il blocco Dec della decodifica e il blocco Exe dell'esecuzione. La freccia gialla indica un accesso in memoria istruzioni (quindi l'uso del bus che fa comunicare CPU con la memoria istruzioni) mentre quella celeste indica un accesso in memoria dati (quindi l'uso del bus che collega la CPU con la memoria dati). La pipeline risulta piena nello slot temporale 3. Esaminando questa situazione si vede che ci sono al massimo 3 accessi contemporanei in memoria; si capisce allora che occorrono 3 bus di cui 1 per le istruzioni e 2 per i dati (la memoria è divisa in una parte dati e una parte istruzioni). Ad ogni ciclo si ha l'esecuzione contemporanea dei blocchi entro lo slot numerato; quindi nello slot 1 reperiamo l'istruzione 1, nello slot 2 reperiamo l'istruzione 2 e decodifichiamo l'istruzione 1, nello slot 3 reperiamo l'istruzione 3, decodifichiamo l'istruzione 2 e eseguiamo l'istruzione 1, ecc. Da questo momento in poi avremo una istruzione eseguita ad ogni colpo di clock. In questo esempio mi sono fermato a sole 3 istruzioni ma pensiamo se le istruzioni da eseguire sono 300!
Naturalmente la pipeline non risulterà sempre efficiente; infatti nel caso si incontrino spesso salti nel programma o interruzioni, bisognerà svuotare la pipeline (finire cioè di eseguire le istruzioni che erano state reperite) e passare al nuovo processo. Se, però, i programmi sono fatti in modo da sfruttare questo congegno il risparmio di tempo è notevole. A dimostrazione di questa cosa vi ricordiamo l'impatto negativo sulle prestazioni che la pipeline delle CPU Pentium 4 ha mostrato, tanto che Intel sta cercando in diversi modi la strada per migliorare il meccanismo di branch prediction o previsione dei salti.
Il costo da pagare è una maggior complessità nel progetto della CPU, una maggior richiesta di risorse hardware e conseguentemente un costo maggiore. Chiaramente abbiamo parlato di una tecnica generica di pipelining; le specializzazioni di tale tecnica dovrebbero essere approfondite caso per caso.