Architetture dei processori/Unità di decodifica: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
Riga 27:
 
== Esecuzione predicativa ==
L'esecuzione predicativa è un approccio che mira a ridurre la dipendenza del processore dall'unità di predizione delle diramazioni. I microprocessori moderni sono dotati di molte unità funzionali in grado di eseguire operazioni in parallelo ma queste unità sono quasi sempre vuote. Processori anche molto complessi come il Pentium 4 pur potendo in teoria eseguire fino a 6 operazioni in contemporanea in realtà per la maggior parte del tempo eseguono una o due operazioni in parallelo. Partendo da questa constatazione l'approccio predicativo punta a riempire al massimo le unità di elaborazione eliminando le istruzioni eseguite ma non necessarie. Un processore dotato di esecuzione predicativa oltre a leggere le istruzioni legge dei predicati associate a esse, questi predicati indicano al processore in caso di salto condizionato quale ramo risulta effettivamente valido. In sostanza in caso di salto condizionato il processore sostituisce la condizione di salto con un predicato (per esempio il predicato P0). Al blocco di istruzioni da eseguire se il salto viene eseguito viene associato il predicato P0=0 mentre al blocco di istruzioni da eseguire nel caso il salto non venga eseguito viene associato il predicato P0=1. Poi il processore esegue in parallelo le istruzioni del primo blocco in una un'unità funzionale e l'istruzione del secondo blocco in una un'altra unità funzionale. L'istruzione di salto in sostanza è stata convertita ilnel predicato che vale 0 oppure 1 e quindi il processore può stabilire quale blocco di istruzioni sia valido semplicemente eseguendo le istruzioni e calcolando il valore di P0 come calcola il valore di ogni operando. Il blocco con le istruzioni non valide viene individuato tramite il predicato loro associato ed eliminato. Questa filosofia di sviluppo quindi preferisce eseguire anche istruzioni inutili pur di mantenere sempre piene le pipeline.
 
Questa metodologia di esecuzione fornisce buone prestazioni se le pipeline non sono formate da troppi stadi. Per esempio un processore come il Pentium 4 è dotato di pipeline da 31 stadi e quindi un'esecuzione predicativa potrebbe portare ad eseguire fino a 31 operazioni inutili prima dell'individuazione del valore di P0 e quindi dell'individuazione delle istruzioni eseguite erroneamente. Il processore Itanium 2, che implementa questa modalità di esecuzione, difatti utilizza pipeline corte, a 8 stadi.
 
L'esecuzione predicativa se non è gestita dal set di istruzioni del processore è molto costosa da implementare. Il processore dovrebbe associare in tempo reale alle istruzioni i vari predicati e tenerne traccia durante l'esecuzione. È da notare che non tutti i salti possono convenientemente essere risolti con i predicati, a volte conviene basarsi sull'unità di predizione dei salti, difatti se il salto coinvolge un blocco con molte istruzioni e si ritiene di poter calcolare con buona probabilità l'esito del salto non conviene utilizzare l'esecuzione predicativa. Quale delle due alternative scegliere dipende dal codice e solo un'analisi di esso permette di individuare l'alternativa migliore, ma un processore, dovendo scegliere in tempo reale qualetra alternativale sceglierealternative, dovrebbe far affidamento su delle euristiche che non sempre danno un risultato ottimale. Invece un processore dotato nativamente di questa modalità di esecuzione deve semplicemente caricare i predicati e regolare correttamente i registri appositi dato che tutta la fase di analisi del codice è stata svolta precedentemente dal compilatore che non avendo problemi di tempo può individuare l'alternativa migliore. Un esempio classico si ha nel caso dei cicli, in un ciclo cha va da 1 a 1000 per esempio un compilatore comprenderebbe che l'esecuzione predicativa non è la scelta ottimale dato che farebbe eseguire per mille volte del codice in più. Invece, se il set di istruzioni lo consente, il compilatore potrebbe indicare al processore che il salto non verrà eseguito permettendo al processore di prevedere per 999 volte la diramazione corretta e sbagliando solo una volta. Invece nel caso di molti IF annidati con condizioni di salto che dipendono da dati esterni e con poche istruzioni controllate dagli IF la strategia predicativa è la migliore soluzione dato che elimina la possibilità di errore ed è in grado di gestire agevolmente anche più condizioni di salto contemporaneamente. Va detto comunque, che in generale l'esecuzione predicativa fornisce risultati peggiori di una buona unità di predizione dei salti. Difatti quasi tutti i processori implementano unità di predizioni dei salti mentre l'esecuzione predicativa è molto meno utilizzata.
 
Ovviamente tutte queste infrastrutture aggiuntive rendono le unità di decodifica molto complesse e queste occupano buona parte dei transistor dei moderni processori. Per ridurre il problema si sono sviluppate architetture come le architetture VLIW e derivate che affrontano il problema alla radice con un paradigma diverso eliminando alcune unità funzionali e semplificandone altre.