...continua...
Il prefetching permette quindi al compilatore di anticipare la necessità di un dato blocco, e di piazzarlo il più possibile vicino alla CPU.
DIPENDENZE FRA DATI
1) Ridenominazione dei registri
Per ridurre l’impatto negativo sulle prestazioni delle dipendenze fra i dati vengono utilizzate due tecniche.
La ridenominazione dei registri distingue fra registri logici e registri fisici; i registri logici sono mappati dinamicamente nei registri fisici attraverso apposite tabelle che vengono aggiornate ogni volta che un’istruzione viene decodificata. Ogni nuovo risultato viene scritto in un registro fisico; tuttavia, il contenuto precedente di ogni registro logico viene salvato, e può essere recuperato nel caso l’istruzione debba essere abortita a causa di un’eccezione o di una previsione di salto non corretta.
Mentre il processore esegue le istruzioni, vengono generati moltissimi risultati temporanei, i quali sono immagazzinati in appositi registri. I valori temporanei diventano permanenti quando la corrispondente istruzione viene "graduata", cioè quando tutte le istruzioni precedenti sono state completate con successo nell’ordine del programma.
Il programmatore è consapevole dell’esistenza dei soli registri logici, mentre l’implementazione dei registri fisici è nascosta.
La ridenominazione dei registri semplifica il controllo delle dipendenze fra i dati. In una macchina che può eseguire istruzioni fuori ordine, i numeri dei registri logici possono diventare ambigui, poiché ad uno stesso registro può essere assegnata una successione di valori diversi. Ma dato che i numeri dei registri fisici identificano in modo unico ogni risultato, il controllo delle dipendenze non risulta più ambiguo.
2) Esecuzione fuori ordine
In un tipico processore che esegue le istruzioni in ordine, ogni istruzione dipende dall’istruzione precedente che produce i suoi operandi, e l’esecuzione non può iniziare finchè questi operandi non diventano validi. Se gli operandi richiesti per eseguire una data istruzione non sono validi, la pipeline stalla finchè tali operandi non diventano disponibili. Poiché le istruzioni vengono eseguite rispettando l’ordine del programma, solitamente gli stalli ritardano tutte le istruzioni seguenti.
In una macchina superscalare "in-order", dove vengono eseguite più istruzioni per ciclo, varie istruzioni consecutive possono iniziare simultaneamente l’esecuzione solo se tutti i loro corrispondenti operandi sono validi, altrimenti il processore và in stallo.
In una macchina superscalare "out-of-order", ogni istruzione può iniziare la sua esecuzione non appena gli operandi necessari diventano disponibili, senza riguardo per la sequenza originaria. L’hardware effettivamente riarrangia l’ordine delle istruzioni per tenere sempre occupate le varie unità di esecuzione. Questo processo viene chiamato dynamic issuing.
PREDIZIONE DEI SALTI
1) Brench Prediction Unit (BPU)
Le diramazioni interrompono il flusso della pipeline; pertanto, per minimizzare il numero di interruzioni, sono necessari degli schemi di branch prediction. Le diramazioni accadono frequentemente, in media ogni sei istruzioni; in un’architettura superscalare, dove vengono eseguite anche quattro istruzioni per ciclo, la predizione di tali diramazioni diventa importante.
Molti schemi di predizione utilizzano degli algoritmi che tengono traccia del comportamento delle diramazioni l’ultima volta che sono state eseguite. Per esempio, se il circuito che memorizza tali comportamenti mostra che la volta precedente un’istruzione ha preso la diramazione, allora si fa l’ipotesi che questa venga presa ancora. Un’implementazione hardware di questa assunzione significa che il programma invierà allo stesso indirizzo tutte le successive diramazioni. La pipeline ora contiene un’istruzione di salto condizionale e altre istruzioni successive ma in quel momento non si sa se tali istruzioni verranno eseguite; infatti se la diramazione non è stata predetta correttamente, le istruzioni nella pipeline devono essere abortite.
Molte architetture implementano un branch stack nel quale vengono salvati gli indirizzi alternativi. Se si prevede che la diramazione non sarà presa, viene salvato l’indirizzo dell’istruzione di branch; in caso contrario viene salvato l’indirizzo immediatamente seguente a tale istruzione.
EVOLUZIONE DELLE CPU
Durante gli ultimi anni, spinte dalle evoluzioni del mercato sia nella crescente domanda di migliori prestazioni, soprattutto in campo grafico e multimediale, che dall’evoluzione di Internet, le principali aziende produttrici si sono date battaglia, più che nel realizzare sistemi veramente innovativi, nel portare all’esasperazione la ricerca della velocità di esecuzione maggiore per mezzo delle tecniche usate negli ultimi 10 anni raggiungendo e superando, anche grazie a nuovi processi tecnologici (nanotecnologie), la soglia dei 4 GHz di clock.
In effetti basta pensare ad Intel che con un ritmo impressionante sorna continuamente CPU con frequenze sempre maggiori...ma credo che ora le acque si siano calmate.
A parte l’esecuzione più veloce delle singole operazioni, che attiene prettamente alla tecnologia impiegata nella realizzazione degli elementi logici e alla loro organizzazione, si possono eseguire un numero maggiore di operazioni in parallelo per incrementare le prestazioni ossia si persegue lo sviluppo a livello di parallelismo delle istruzioni (ILP). Le strade maestre per questo obbiettivo sono essenzialmente la realizzazione di pipeline più profonde (cioè con un numero di stadi maggiore) e la superscalarità che devono essere però accompagnate da tecniche di controllo e predizione delle diramazioni e riordino delle istruzioni.
L’esecuzione in pipeline è naturalmente favorita da istruzioni di ridotta complessità e questo è uno dei motivi per cui gran parte delle risorse dei moderni processori x86 sono spese in fase di decodifica per scomporre le complesse (e di lunghezza variabile) istruzioni del ISA x86 in istruzioni like-RISC da inviare alle diverse unità di esecuzione. Analogamente tecniche come la predizione delle diramazioni o l’esecuzione fuori ordine contribuiscono a spostare la complessità dal software all’hardware, aspetto che sarebbe in contraddizione con la filosofia RISC, ma vengono adottate da moltissimi processori di ispirazione RISC perché consentono alte prestazioni.
Molti processori, implementando l’esecuzione fuori ordine, richiedono anche tecniche di gestione delle false dipendenze dei dati come la ridenominazione dei registri (register renaming, cfr più in alto) che consiste in una mappatura dinamica dei registri architetturali su un set più esteso di registri fisici. Questo avviene anche per un processore RISC come il G4 che possiede un numero maggiore di registri indirizzabili rispetto a un processore di architettura x86 e dovrebbe avvertire meno questa esigenza. I processori più recenti hanno adottato soluzioni tutto sommato convenzionali in questi campi e le poche novità derivano dalla spinta del progresso tecnologico che ha consentito soluzioni quantitativamente diverse soprattutto per gestire l’aumentata profondità delle pipeline (ad esempio si pensi alla pipeline del Pentium4 di ben 20 stadi).
|