IZ5FCY
Minestra riscaldata 'un fu mai bòna
MICROPROCESSORI E MICROCONTROLLORI
… studiare, studiare ed ancora studiare, è il solo modo di capire quanto possa essere grande sia la propria ignoranza!
ARCHITETTURE PARALLELE DELLA CPU
Architetture parallele delle CPU L’obiettivo comune dei progettisti è quello di migliorare l’efficienza della funzionalità del computer e in particolare della CPU. Il miglioramento dell’efficienza segue due strade: l’eliminazione dei colli di bottiglia; l’Instruction Level Parallelism (ILP). Per eliminare i colli di bottiglia, sono state introdotte le cache di primo livello, solitamente interne al microprocessore, e le cache di secondo livello, poste tra il microprocessore e il banco di memoria.
L’ILP consiste nell’aggiungere ulteriori risorse hardware all’interno della CPU allo seguire simultaneamente più istruzioni. Le risorse hardware possono essere registri e unità funzionali (ALU, shifter, floating point unit). Un esempio classico di ILP è la tecnica del pipelining mediante aggiunta di registri e hardware di controllo. La tecnica del parallelismo ha portato a implementare le architetture pipelined, superscalari e vettoriali. Architettura pipelined In un microprocessore con architettura pipeline a ogni ciclo di clock viene eseguita una istruzione (CPI = 1), se non si verificano stalli e conflitti. Nelle CPU tradizionali le istruzioni vengono eseguite in maniera sequenziale, come indicato nella figura a lato. Nei microprocessori senza pipeline ogni istruzione si compone di due fasi: fetch ed execute. Nei microprocessore con pipeline ogni istruzione è suddivisa in quattro fasi: fetch, prelievo; decode, decodifica; operate, elaborazione; write, scrittura risultati.
La struttura a pipeline, utilizzata abbondantemente nei processori RISC, ha come modello la catena di montaggio: durante l’esecuzione di un’istruzione è possibile prepararsi a prelevare l’istruzione successiva. L’idea del pipelinig consiste nell’inserire tra le unità che svolgono le operazioni di fetch e di execute un buffer di memoria, come indicato in figura (a) a lato. Il buffer, che consente alle due unità di comunicare tra loro costituisce l’elemento di pipelining. Le caratteristiche di tale struttura sono le seguenti: ogni istruzione è eseguita in un ciclo completo di clock, come nelle CPU tradizionali; aumenta notevolmente il throughput, ovvero il numero di istruzioni al secondo. Dalla figura (b) si nota che durante la fase di execute della prima istruzione si esegue la fase di fetch della seconda istruzione. Tuttavia la struttura pipelined presenta alcuni problemi: tutti gli stadi devono funzionare in sincronismo, quindi la frequenza del clock deve essere dimensionata sullo stadio più lento; se il dato da prelevare è nella cache, la latenza è estremamente bassa, ma se il dato deve essere prelevato dalla memoria, perché è qui residente o per problemi di cache miss, sono necessari vari cicli di clock per eseguire l’operazione.
Uno dei metodi per aumentare il livello di parallelismo è quello di aumentare la profondità della pipeline con un conseguente aumento del throughput. Il throughput è la frequenza massima con cui le istruzioni escono dalla pipeline. Tuttavia un elevato livello di parallelismo comporta due problemi: presenza di hazard (alee) nella pipeline a causa del read-before-write, ovvero la necessità per una istruzione di attendere il risultato di un’altra istruzione a livello superiore; tale problema porta a uno stallo della pipeline; effetto negativo sul funzionamento della pipeline per la presenza di salti nel programma. Nei microprocessori attualmente in commercio la profondità si aggira tra i 10 e i 15 buffer.
Facendo riferimento ala soprastante figura, il primo stadio preleva l’istruzione, il secondo decodifica e preleva gli operandi, il terzo esegue l’operazione e il quarto scrive i risultati. Con questo tipo di struttura ogni stadio compie operazioni più elementari consentendo di aumentare la frequenza del clock. Con quattro stadi, come nelle fgure (a) e (b) aumenta la latenza ma aumenta anche il throughput. Le prestazioni della pipeline dipendono fortemente dalla presenza degli hazard. Si verifica un hazard quando uno stadio non può eseguire un’istruzione in quel dato ciclo di clock. Gli hazard possono essere di tre tipi: • strutturali; • di dato; • di controllo Gli hazard mandano in stallo la pipeline. Più elevata è la frequenza degli hazard peggiore sarà la prestazione della pipeline. Compito del progettista è quello di ridurre al minimo le probabilità di hazard. Un hazard è strutturale quando due stadi devono condividere la stessa risorsa hardware, ad esempio devono accedere entrambi alla ALU. Un altro problema che si presenta frequentemente nella pipeline è il data dependency (hazard di dato). Per esempio, se l’istruzione I2 utilizza un risultato dell’istruzione I1, in questo caso il compilatore, che deve essere in grado di riconoscere il problema di data dependency, per evitare lo stallo, introduce cicli di NOP tra le due istruzioni. Un metodo per eliminare il data dependency è l’uso dei registri virtuali. Nei registri della pipeline, i posti riservati per memorizzare gli operandi delle istruzioni possono essere visti come registri virtuali che possono essere raggiunti direttamente. Quando un’istruzione sta aspettando i dati di una istruzione non ancora eseguita, effettua la lettura nel registro virtuale evitando l’operazione più lunga di lettura in memoria. Quando l’istruzione, che deve generare il risultato atteso anche dall’istruzione in parallelo, ha terminato il lavoro, memorizza il risultato nel proprio registro virtuale, nel registro virtuale dell’altra istruzione e in memoria. L’eliminazione della lettura in memoria migliora la prestazione del microprocessore. Un hazard di controllo si presenta quando il micro non sa dove trasferire il controllo perché non è ancora stato determinato se e dove saltare. Un esempio di hazard si presenta anche quando si verifica la cache miss. Il problema può essere risolto complicando l’hardware della CPU, ma in generale i progettisti preferiscono mantenere un hardware semplice, per avere una frequenza di clock quanta più elevata possibile, e demandare il problema al software. Per evitare conflitti tra i vari stadi viene implementata all’inizio della pipeline una cache dedicata alle istruzioni. Un altro problema che può causare lo stallo della pipeline è relativo al salto, poiché alcuni stadi possono eseguire istruzioni indesiderate. Allo scopo di limitare i problemi di stallo, la pipeline viene dotata di una unità che preleva (prefetching) una certa quantità di istruzioni e, dopo aver riconosciuto i salti, le ordina in coda in modo opportuno . L’unità di dispatch preleva le istruzioni dalla testa della instruction queue e le invia allo stadio di esecuzione. È importante avere una coda abbastanza lunga perché si può avere stallo: nella pipeline ma l’unità di fetch può continuare a caricare altre istruzioni; nell’unità di fetch, in questo caso la pipeline può continuare a eseguire le istruzioni. La branch delay instruction è l’istruzione immediatamente successiva a una istruzione di salto condizionato. Tale branch delay instruction viene eseguita anche se non si verificano le condizioni per il salto. Nelle architetture pipeline la posizione di questa istruzione è definita branch delay slot. Il branch delay slot è chiaramente un effetto indesiderato della pipeline che può essere riempito in due modi: si affida al compilatore il compito di riordino in modo tale da eseguire quelle istruzioni che comunque vanno eseguite perché non dipendenti dal salto; si applica la tecnica di branch prediction, ovvero si cerca di prevedere l’esito del salto condizionato; poiché non è certo che quanto predetto sarà valicato successivamente, si definisce speculativa questa architettura.
Pipeline a 4 stadi (a); pipelining delle istruzioni (b).
Con la predizione e l’esecuzione speculativa è possibile utilizzare in modo più efficiente la maggior parte degli slot presenti nella pipeline limitando gli stalli dovuti alle istruzioni di salto. I microprocessori più moderni sono dotati di una Branch Prediction Unit che consiste in una unità che ha il compito di prevedere l’istruzione successiva da eseguire quando si prese- -ntano salti condizionati. L’unità di predizione conferisce al microprocessori una notevole accelerazione, ma anche il rischio di un restart della pipeline in caso di predizione errata. Il funzionamento dell’unità di branch prediction si basa su un algoritmo misto, statico e dinamico. L’algoritmo dinamico valuta la storia delle predizioni precedenti di quella istruzione. Se l’istruzione si presenta per la prima volta, si basa sull’algoritmo statico. L’algoritmo statico basa la sua valutazione su decisioni prefissate. L’evoluzione del pipelining ha portato a progettare un’architettura superscalare.
Architettura superscalare Per aumentare il livello di parallelismo, si può, in alternativa all’aumento della profondità, adottare la strategia della tecnica multiple issue. Questa tecnica consiste nell’aumentare le unità indipendenti di esecuzione delle istruzioni, con l’obiettivo finale di avere CPI < 1, ovvero meno di un ciclo di clock per ogni istruzione. L’architettura superscalare (letteralmente oltre (super) unidimensionale (scalare)), nata in ambiente RISC, consiste nell’implementare più pipeline in parallelo. Le pipeline possono essere uguali o differenti. Quando le pipeline sono tutte uguali, condividono gli stessi registri, con probabilità molto elevata di conflitti e dipendenze. In questo caso per limitare i problemi, tutte le pipeline devono vedere registri virtuali. Un micro di questo tipo è l’ALPHA della DEC. Nella maggior parte dei microprocessori invece vi sono pipeline differenti perché ognuna è specializzata nell’eseguire operazioni differenti. Per esempio alcune operano in floating point e altre elaborano numeri interi. In questo caso le pipeline prelevano solo le istruzioni che possono eseguire, non sono soggette alla dipendenza tra loro e utilizzano risorse (registri) differenti. Le unità di fetch e di dispatch (vedi la soprastante figura) operano su più istruzioni contemporaneamente. I microprocessori con questo tipo di architettura sono in grado di eseguire più di una istruzione per ciclo di clock. Una particolare importanza riveste il ruolo dell’unità di dispatch che è più sofisticata in quanto deve essere in grado di scegliere e smistare le istruzioni sulle varie pipeline. I processori superscalari operano nel seguente modo: prelevano istruzioni dalla memoria; prelevano e decodificano molte istruzioni alla volta dal flusso di istruzioni ricevute; contemporaneamente valutano i risultati dei branch condizionali in anticipo in modo tale da assicurare alle pipeline un flusso ininterrotto di istruzioni. L’architettura scalare utilizza l’ILP dinamico per individuare le istruzioni da eseguire parallelamente. In questo tipo di architettura la presenza degli hazard può essere molto più grave rispetto alla pipeline semplice. I vantaggi dell’architettura superscalare sono i seguenti: la struttura è compatibile con qualunque ISA, ed è utilizzabile sia dai CISC sia dai RISC; la programmazione assembly e il compilatore vedono un codice sequenziale come nelle CPU scalari. Gli svantaggi invece si possono così riassumere: hardware di controllo abbastanza complesso perché il livello di parallelismo grava esclusivamente sull’hardware; lo scheduling delle istruzioni è a run-time; out-of-order execution, conseguenza dell’ILP dinamico ciclo di clock più lungo. Lo scheduling delle istruzioni consiste nel riordino delle istruzioni in modo tale che possano essere eseguite senza gli stall. Lo scheduling è a run-time (o dinamico) quando viene eseguito durante l’esecuzione delle istruzioni, mentre è a compile time quando viene realizzato in fase di programmazione
Architettura VLIW L’architettura VLIW (Very Long Instruction Word) è una struttura nella quale il parallelismo delle istruzioni (ILP) è di tipo statico e quindi demandato al compilatore. Con la tecnica VILW, come con la superscalare, si può ottenere CPI < 1, ovvero eseguire una istruzione in un tempo inferiore a un ciclo di clock. Lo scheduling delle istruzioni è a compile-time. Al compilatore viene descritto l’hardware del processore in modo tale da impacchettare in un’unica Very Long Instruction Word una serie di istruzioni che si possono eseguire parallelamente. Il compilatore crea un POE (Plan Of Execution) formato da serie di istruzioni molto lunghe. Affinché possa assolvere al compito di schedulare in modo corretto le operazioni all’interno delle very long instruction, il compilatore deve: conoscere il numero e il tipo di unità funzionali per stabilire quali istruzioni e di quale tipo si possono inserire nella stessa word; conoscere la latenza delle operazioni per sapere quanti cicli di clock servono per eseguire le operazioni. Le unità funzionali, che sono associate alle operazioni da eseguire, sono: • la ALU in FP (Floating Point); • la ALU per integer (per elaborare i numeri interi); • l’unità load/store che provvede a leggere e scrivere i dati dai registri alla memoria.
L’hardware di questi processori è molto semplice perché si deve limitare a eseguire il POE deciso dal compilatore. Le istruzioni VLIW sono lunghe da 256 a 1024 bit. I vantaggi dei processori VLIW sono i seguenti: semplificazione dell’hardware di controllo con conseguente diminuzione della potenza e dell’aumento del clock; la modifica dello scheduling software del compilatore è più facile della modifica dell’hardware di controllo; il sistema è scalabile perchè si può aumentare il livello di parallelismo aumentando la issue-width (numero massimo di slot-operazioni) in un bundle (pacchetto di istruzioni). il codice VLIW è più compatto rispetto ad altre soluzioni. Gli svantaggi sono: in presenza di eventi quali cache miss hanno un comportamento meno flessibile dei superscalari; il software per processori VLIW deve essere ricompilato per essere esportato su altri processori; ad esempio una word che richiede tre unità funzionali FP e che ha una certa latenza non può essere riproposta in modo identico per altri processori con due unità FP; i processori EPIC, evoluzione dei VLIW, non sono compatibili tra loro e con i precedenti VLIW.
Raffigurato a lato è riportato un confronto tra le architetture di una CPU classica e di quella VLIW
Architettura EPIC L’architettura EPIC (Explicitly Parallel Instruction Computing), è nata per superare i limiti della VLIW. Il limite più evidente dell’architettura VLIW è quello di essere strettamente collegata al tipo di hardware implementato in quella classe di microprocessore. Cambiando tipologia di micro è necessario ricompilare il codice sul nuovo hardware. La richiesta degli utenti è invece proprio quella di mantenere il software con CPU differenti. Allo scopo di superare questi problemi della VLIW, alcune case costruttrici hanno sviluppato soluzioni alternative una di queste è la EPIC. L’architettura EPIC, nata alla fine degli anni ’90 come evoluzione della VLIW, sviluppata da Intel e HP, ha portato alla struttura IA-64 utilizzata nei processori Itanium e Itanium2. La EPIC ha 2 caratteristiche che la differenziano dalla VLIW: una spiccata collaborazione tra hardware e software; un numero più elevato di registri.
Confronto tra l’architettura di una CPU classica e di una VLIW.
Le istruzioni vengono raggruppate in word, come nell’architettura VLIW, ma sono integrate con informazioni sul parallelismo tra le varie word. In questo modo anche se varia l’hardware interno, i microprocessori possono utilizzare ugualmente lo stesso codice. Le unità di decodifica, che possono essere anche circuitalmente semplici poiché lo scheduling è effettuato dal compilatore, utilizzano le informazioni sul parallelismo in modo efficiente. Per migliorare le prestazioni, nel micro EPIC sono state aggiunte: alcune centinaia di registri per non implementare l’unità di ridenominazione dinamica dei registri, visibili al compilatore; alcune istruzioni predicative per evitare lo svuotamento delle pipeline; alcune soluzioni innovative che consentono di velocizzare i cambi di contesto tra le subroutine e per migliorare la gestione della cache.
Naturalmente l’aggiunta di altri registri a quelli già esistenti (generali, predicativi, float, re-naming e stack) porta i transistor a un totale di 1,72 miliardi.
ILP dinamico e statico L’ILP dinamico è una tecnica circuitale che consente di individuare le istruzioni che si possono eseguire in modo parallelo. Pertanto il livello di parallelismo è affidato esclusivamente all’hardware. L’ILP dinamico si realizza in vari modi: out-of-order; predizione dei branch; esecuzione speculativa; rinominazione dei registri. Quando si utilizza la struttura a pipeline non tutte le istruzioni possono essere eseguite parallelamente. Infatti una istruzione può utilizzare dati che si ottengono come risultati da istruzioni precedenti. Ad esempio: L’istruzione necessita del risultato della prima istruzione per essere eseguita. La pipeline che esegue la deve essere mandata in stallo. Dalla lista delle istruzioni si nota che la non dipende dalle altre due, quindi inviando nella pipeline nell’ordine si evita di introdurre gli stalli. La sequenza nell’esecuzione delle istruzioni porta però all’out-of-order ovvero a un fuori ordine nella generazione dei risultati rispetto allo sviluppo del programma. In presenza di un salto un’unità di predizione esamina i casi precedenti che si sono verificati con lo stesso tipo di istruzione e valuta se il salto avverrà o meno. Se la predizione è esatta la pipeline non viene bloccata, in caso contrario viene svuotata per ripartire nuovamente. Basandosi su una statistica dei casi precedenti di salto, il processore esegue in modo speculativo il salto ottenendo dei risultati. Se tali risultati risultano esatti il micro ha guadagnato tempo, se invece l’esecuzione speculativa si rivela errata, i risultati vengono annullati. Alcune istruzioni pur essendo indipendenti possono utilizzare lo stesso registro per la memorizzazione del risultato. Il microprocessore utilizza altri registri per memorizzare temporaneamente i dati e allocarli successivamente nello stesso registro e nella stessa sequenza indicata dal programma.
In presenza di un salto un’unità di predizione esamina i casi precedenti che si sono verificati con lo stesso tipo di istruzione e valuta se il salto avverrà o meno. Se la predizione è esatta la pipeline non viene bloccata, in caso contrario viene svuotata per ripartire nuovamente. Basandosi su una statistica dei casi precedenti di salto, il processore esegue in modo speculativo il salto ottenendo dei risultati. Se tali risultati risultano esatti il micro ha guadagnato tempo, se invece l’esecuzione speculativa si rivela errata, i risultati vengono annullati. Alcune istruzioni pur essendo indipendenti possono utilizzare lo stesso registro per la memorizzazione del risultato. Il microprocessore utilizza altri registri per memorizzare temporaneamente i dati e allocarli successivamente nello stesso registro e nella stessa sequenza indicata dal programma. Con l’ILP statico il parallelismo delle istruzioni viene deciso nella fase di compilazione del codice. Infatti il compilatore, dopo aver analizzato il programma, rileva le istruzioni che si possono eseguire simultaneamente. Il micro esegue le istruzioni già organizzate dal compilatore, quindi è molto più semplice da un punto di vista dell’hardware. L’ILP statico è utilizzato nei microprocessori embedded per problemi di spazio, consumi e costi perché i micro con ILP dinamico hanno un hardware molto complesso. I processori Itanium della Intel utilizzano l’ILP statico.

Lorem Ipsum Dolor

Cupidatat excepteur ea dolore sed in adipisicing id? Nulla lorem deserunt aliquip officia reprehenderit fugiat, dolor excepteur in et officia ex sunt ut, nulla consequat. Laboris, lorem excepteur qui labore magna enim ipsum adipisicing ut. Sint in veniam minim dolore consectetur enim deserunt mollit deserunt ullamco. Mollit aliqua enim pariatur excepteur. Labore nulla sunt, in, excepteur reprehenderit lorem fugiat. Ipsum velit sunt! Non veniam ullamco amet officia ut, ex mollit excepteur exercitation fugiat eu ut esse cupidatat in velit. Non eu ullamco in pariatur nisi voluptate mollit quis sed voluptate ea amet proident dolore elit. Occaecat nostrud dolore sunt, ullamco eu ad minim excepteur minim fugiat. Nostrud culpa eiusmod dolor tempor et qui mollit deserunt irure ex tempor ut dolore. Dolore, nostrud duis ad. In nulla dolore incididunt, sit, labore culpa officia consectetur mollit cupidatat exercitation eu. Aute incididunt ullamco nisi ut lorem mollit dolore, enim reprehenderit est laborum ut et elit culpa nulla. Excepteur fugiat, laboris est dolore elit. In velit lorem id, et, voluptate incididunt ut ad in sunt fugiat, esse lorem. Nisi dolore ea officia amet cillum officia incididunt magna nisi minim do fugiat ut nostrud dolore Qui in est in adipisicing ea fugiat aliqua. Reprehenderit excepteur laboris pariatur officia sit amet culpa aliquip quis elit eiusmod minim. Sint ut ut, proident in mollit do qui eu. Pariatur et cupidatat esse in incididunt magna amet sint sit ad, sunt cillum nulla sit, officia qui. Tempor, velit est cillum sit elit sed sint, sunt veniam.
Add your one line caption using the Image tab of the Web Properties dialog
LOGOTYPE
© Irure ut pariatur ad ea in ut in et. In incididunt sed tempor