09.06.2013 Views

Oltre la legge di Moore: evoluzioni architetturali dei processori Intel ...

Oltre la legge di Moore: evoluzioni architetturali dei processori Intel ...

Oltre la legge di Moore: evoluzioni architetturali dei processori Intel ...

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Università degli Stu<strong>di</strong> <strong>di</strong> Modena e Reggio Emilia<br />

Facoltà <strong>di</strong> Ingegneria <strong>di</strong> Modena<br />

Corso <strong>di</strong> Laurea in Ingegneria Elettronica<br />

Vecchio Or<strong>di</strong>namento Didattico<br />

<strong>Oltre</strong> <strong>la</strong> <strong>legge</strong> <strong>di</strong> <strong>Moore</strong>:<br />

<strong>evoluzioni</strong> <strong>architetturali</strong><br />

<strong>dei</strong> <strong>processori</strong> <strong>Intel</strong> fino a Nehalem<br />

Re<strong>la</strong>tore: Can<strong>di</strong>dato:<br />

Prof. Rita Cucchiara Marco Vezzani<br />

Anno Accademico 2007/2008


Sommario<br />

Sommario ............................................................................................................. 3<br />

In<strong>di</strong>ce delle figure ................................................................................................ 7<br />

Ringraziamenti ................................................................................................... 13<br />

Capitolo 1 - Introduzione ................................................................................... 15<br />

Capitolo 2 - Il calcolo delle prestazioni ............................................................. 19<br />

2.1 Prestazioni in termini <strong>di</strong> Velocità ............................................................ 19<br />

2.1.1 Tcpu .................................................................................................. 22<br />

2.1.2 MIPS ................................................................................................. 24<br />

2.2 Prestazioni in termini <strong>di</strong> Consumo (potenza ed efficienza energetica) .... 26<br />

2.3 Possibili approcci per l’aumento delle prestazioni .................................. 28<br />

2.3.1 Uno sguardo all’evoluzione tecnologica ........................................... 29<br />

2.3.2 Corsa al gigahertz e il limite <strong>dei</strong> 4 GHz ............................................ 33<br />

2.4 Legge <strong>di</strong> Amdahl ..................................................................................... 35<br />

Capitolo 3 - Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni .... 41<br />

3.1 Introduzione ............................................................................................. 41<br />

3.2 Parallelismo ............................................................................................. 42<br />

3.2.1 Instruction Level Parallelism ............................................................ 45<br />

3.2.2 Multithrea<strong>di</strong>ng .................................................................................. 88<br />

3.2.3 Multi core .......................................................................................... 95<br />

3.2.4 Parallelismo <strong>dei</strong> dati e Unità Vettoriali ............................................. 98<br />

3.2.5 Limiti sul livello <strong>di</strong> parallelismo ..................................................... 102


4 In<strong>di</strong>ce delle figure<br />

3.3 Cache ..................................................................................................... 103<br />

3.3.1 Politiche <strong>di</strong> rimpiazzamento ........................................................... 106<br />

3.3.2 Politiche <strong>di</strong> salvataggio ................................................................... 107<br />

3.3.3 Protocolli <strong>di</strong> coerenza ..................................................................... 108<br />

3.3.4 Associatività .................................................................................... 108<br />

3.3.5 Obiettivo: Minimizzare i Cache miss ............................................. 111<br />

3.3.6 Gerarchie delle cache ...................................................................... 115<br />

3.4 Set <strong>di</strong> Istruzioni ...................................................................................... 122<br />

Capitolo 4 - Il risparmio energetico ................................................................. 125<br />

Capitolo 5 - Applicazione nei <strong>processori</strong> <strong>Intel</strong>® ............................................. 127<br />

5.1 I <strong>processori</strong> del<strong>la</strong> <strong>Intel</strong> ® Corporation ..................................................... 127<br />

5.2 Modello Tick tock .................................................................................. 127<br />

5.3 Nomi delle architetture e re<strong>la</strong>tive CPU .................................................. 130<br />

5.4 Parallelismo “on Chip” .......................................................................... 131<br />

5.4.1 Pipeline ........................................................................................... 131<br />

5.4.2 Processori Supersca<strong>la</strong>ri ................................................................... 173<br />

5.4.3 Pre<strong>di</strong>zione <strong>dei</strong> salti .......................................................................... 174<br />

5.4.4 VLIW e Tecniche Pre<strong>di</strong>cative ......................................................... 180<br />

5.4.5 Multithrea<strong>di</strong>ng ................................................................................ 182<br />

5.4.6 Multicore ......................................................................................... 189<br />

5.5 Parallelismo a livello <strong>di</strong> dato ................................................................. 190<br />

5.6 Nuove tecnologie per le cache <strong>di</strong> <strong>Intel</strong> ®<br />

................................................. 192<br />

5.7 Set <strong>di</strong> Istruzioni ...................................................................................... 194<br />

5.7.1 IA-32: CISC o RISC? ..................................................................... 194


5.7.2 Tecnologia SIMD ........................................................................... 196<br />

5.8 Il risparmio energetico ........................................................................... 204<br />

Capitolo 6 - Il nuovo processore Core i7 ......................................................... 207<br />

6.1 Elementi base del<strong>la</strong> nuova architettura .................................................. 207<br />

6.2 Design modu<strong>la</strong>re .................................................................................... 209<br />

6.3 Architettura dell’engine ......................................................................... 209<br />

6.4 HyperThrea<strong>di</strong>ng, ritorno al passato ........................................................ 212<br />

6.5 Modelli ................................................................................................... 213<br />

6.6 Architettura del<strong>la</strong> cache ......................................................................... 215<br />

6.7 Memory controller integrato .................................................................. 217<br />

6.8 NUMA ................................................................................................... 217<br />

6.9 QuickPath Interconnect .......................................................................... 218<br />

6.10 Istruzioni SSE 4.2 ................................................................................ 219<br />

6.11 Turbo Mode ......................................................................................... 219<br />

6.12 Consumi ............................................................................................... 221<br />

6.13 Considerazioni finali ............................................................................ 223<br />

Capitolo 7 - Le architetture del futuro ............................................................. 225<br />

7.1 La <strong>legge</strong> <strong>di</strong> Amdahl nell’era del multicore ............................................ 225<br />

7.2 Una rivoluzione del pensiero comune .................................................... 231<br />

7.3 “I sette nani” .......................................................................................... 236<br />

7.4 Lo stu<strong>di</strong>o dell’ <strong>Intel</strong> ® : RMS ................................................................... 238<br />

7.5 Autotuners .............................................................................................. 243<br />

7.6 Nuove metriche <strong>di</strong> valutazione .............................................................. 246<br />

Capitolo 8 - Le architetture del futuro ............................................................. 249<br />

5


6 In<strong>di</strong>ce delle figure<br />

Appen<strong>di</strong>ce A - Storia del<strong>la</strong> <strong>Intel</strong>® Corporation ............................................... 251<br />

Appen<strong>di</strong>ce B - Storia <strong>dei</strong> <strong>processori</strong> <strong>Intel</strong>® ..................................................... 255<br />

Cenni sul<strong>la</strong> evoluzione <strong>dei</strong> <strong>processori</strong> <strong>Intel</strong> ® precedenti al Pentium ............ 255<br />

Evoluzione <strong>dei</strong> <strong>processori</strong> <strong>Intel</strong> ® a partire dal Pentium ............................... 265<br />

Bibliografia ...................................................................................................... 279


In<strong>di</strong>ce delle figure<br />

Figura 1.1 - Incremento delle prestazioni a seguito <strong>di</strong> miglioramenti tecnologici<br />

e <strong>architetturali</strong>. ................................................................................................... 16<br />

Figura 2.1 - Grafico delle prestazioni in MIPS delle CPU <strong>Intel</strong> ® dall'8086 al<br />

Pentium ®<br />

............................................................................................................ 26<br />

Figura 2.2 - Confronto tra <strong>la</strong> <strong>legge</strong> <strong>di</strong> <strong>Moore</strong> e l’incremento delle prestazioni . 29<br />

Figura 2.3 – Grafico originale <strong>di</strong> Goordon <strong>Moore</strong> del 1965[6]. ........................ 30<br />

Figura 2.4 -Aumento del numero <strong>di</strong> transistori delle CPU <strong>Intel</strong> ® .<br />

Figura 2.5 – Aumento del numero <strong>di</strong> transistori nelle CPU <strong>Intel</strong> ® [8] ................ 33<br />

Figura 2.6 - Densità <strong>di</strong> potenza <strong>di</strong>ssipata dalle CPU .......................................... 34<br />

Figura 2.7 - I risultati mostrano come un incremento anche minimo nelle<br />

prestazioni <strong>di</strong> una parte utilizzata per parecchio tempo sia complessivamente<br />

più rilevante <strong>di</strong> un miglioramento importante <strong>di</strong> parti poco utilizzate. .............. 38<br />

Figura 3.1 - Diversi tipi <strong>di</strong> parallelismo applicabile ai sistemi <strong>di</strong> e<strong>la</strong>borazione. 42<br />

Figura 3.2 - Tassonomia <strong>di</strong> Flynn per <strong>la</strong> c<strong>la</strong>ssificazione <strong>dei</strong> sistemi paralleli ... 48<br />

Figura 3.3 - Passaggi fonfdamentali <strong>di</strong> una pipeline .......................................... 50<br />

Figura 3.4- E<strong>la</strong>borazione <strong>di</strong> istruzioni senza pipeline. ....................................... 50<br />

Figura 3.5- Esecuzione <strong>di</strong> istruzioni con pipeline .............................................. 51<br />

Figura 3.6- La necessità <strong>di</strong> aspettare il dato <strong>di</strong>sponibile genera una “bol<strong>la</strong>” nel<strong>la</strong><br />

pipeline che comporta una riduzione del throughput. ........................................ 53<br />

Figura 3.7- La pipeline del Pentium ® 4 costituita da 20 sta<strong>di</strong> ............................. 54<br />

Figura 3.8 - Schema concettuale dell’esecuzione fuori or<strong>di</strong>ne. ......................... 60<br />

Figura 3.9 - Organizzazione <strong>di</strong> una pipeline col metodo del Reordering Buffer<br />

........................................................................................................................... 61<br />

Figura 3.10- Percorsi <strong>di</strong> by-pass e ROB. ........................................................... 64<br />

32<br />

7


8 In<strong>di</strong>ce delle figure<br />

Figura 3.11- Organizzazione del<strong>la</strong> pipeline con un History Buffer (HB). ......... 65<br />

Figura 3.12- Gli stati possibili del<strong>la</strong> pre<strong>di</strong>zione bimodale ................................. 71<br />

Figura 3.13 - Crescita del GAP tra <strong>la</strong> velocità delle memorie e delle CPU ....... 86<br />

Figura 3.14 - Un processore single thread esegue un solo thread per volta ....... 89<br />

Figura 3.15 -Un sistema multiprocessore c<strong>la</strong>ssico esegue un thread per unità <strong>di</strong><br />

calcolo ................................................................................................................ 89<br />

Figura 3.16 - Un sistema superthrea<strong>di</strong>ng schedu<strong>la</strong> più thread ma ne esegue uno<br />

solo per ciclo <strong>di</strong> clock ........................................................................................ 90<br />

Figura 3.17 - Un sistema Simultaneous Multi-Threa<strong>di</strong>ng .................................. 95<br />

Figura 3.18 – Schema a blocchi <strong>di</strong> una architettura vettoriale ......................... 101<br />

Figura 3.19 –Modalità <strong>di</strong> riempimento del<strong>la</strong> cache nel caso <strong>di</strong> memoria cache<br />

“Mappata Direttamente” e “Associativa a 2 vie” ............................................. 109<br />

Figura 3.20 - Frequenza <strong>di</strong> fallimento (miss rate) a confronto con <strong>la</strong> <strong>di</strong>mensione<br />

del<strong>la</strong> cache (Cache size) sul<strong>la</strong> porzione degli interi <strong>di</strong> SPEC CPU2000 ......... 113<br />

Figura 3.21 - Un esempio <strong>di</strong> architettura con 3 livelli <strong>di</strong> cache. ...................... 120<br />

Figura 3.22 – CISC vs RISC[15] ..................................................................... 123<br />

Figura 5.1 – Tick-tock in azione. ..................................................................... 129<br />

Figura 5.2-Per <strong>la</strong> sua politica <strong>di</strong> update <strong>Intel</strong> ® ha coniato il termine tick-tock<br />

(equivalente del tic-tac italiano). ...................................................................... 130<br />

Figura 5.3 – La integer pipeline del processore 486[17] ................................. 132<br />

Figura 5.4 – Schema a blocchi del<strong>la</strong> CPU 486. [18] ........................................ 134<br />

Figura 5.5 – La integer pipeline del Pentium.[17] ........................................... 135<br />

Figura 5.6 - Architettura interna del processore Pentium[17] ......................... 136<br />

Figura 5.7- LA FPU del processore Pentium[17] ............................................ 139<br />

Figura 5.8 – Struttura del<strong>la</strong> pipeline MMX [19] .............................................. 142


Figura 5.9 - Introduzione del Buffer FIFO e dello sta<strong>di</strong>o PF nel<strong>la</strong> pipeline MMX<br />

rispetto a quel<strong>la</strong> del Pentium ® [20] .................................................................. 143<br />

Figura 5.10 - Flusso <strong>di</strong> istruzioni MMX nel processore Pentium ® con tecnologia<br />

MMX ............................................................................................................... 144<br />

Figura 5.11 - Tipi <strong>di</strong> istruzioni MMX e re<strong>la</strong>tive unità funzionali [19] ............ 144<br />

Figura 5.12 - La pipeline del processore Pentium ® Pro [19] ........................... 145<br />

Figura 5.13 – In order FrontEnd del Pentium ® Pro [19] ................................... 147<br />

Figura 5.14 - L'Out-of order Core del Pentium ® Pro [19] ................................ 149<br />

Figura 5.15 - Execution units del Pentium ® Pro. [19] ..................................... 150<br />

Figura 5.16 - Retirement unit del Pentium ® Pro ............................................... 150<br />

Figura 5.17 - Execution units del Pentium ® II ................................................. 151<br />

Figura 5.18 - Architettura del Pentium ® II e del Pentium ® III [21] ................... 152<br />

Figura 5.19 - Execution unit e porte del core Out-of-order del Pentium ® III [21]<br />

......................................................................................................................... 152<br />

Figura 5.20 – Execution Unit del Pentium ® III.. ............................................... 153<br />

Figura 5.21 - Microarchitettura <strong>Intel</strong> ® NetBurst [22] ...................................... 155<br />

Figura 5.22- Execution Unit e porte del<strong>la</strong> architettura NetBurst. [22] ............ 159<br />

Figura 5.23 - Schema a blocchi dell'architettura del Pentium ® 4 [23] .............. 161<br />

Figura 5.24 - Funzionamento del<strong>la</strong> pipeline del<strong>la</strong> microarchitettura <strong>Intel</strong> ®<br />

Core[24] ........................................................................................................... 163<br />

Figura 5.25- Elementi del Front End del<strong>la</strong> microarchitettura Core [24] .......... 164<br />

Figura 5.26 - Issue ports del<strong>la</strong> Microarchitettura <strong>Intel</strong> ® Core. La tabel<strong>la</strong> mostra I<br />

dati per due modelli <strong>di</strong> processore. [24] ........................................................... 166<br />

Figura 5.27 - Execution core del<strong>la</strong> microarchitettura <strong>Intel</strong> ® Core [24] ............ 167<br />

Figura 5.28 - Funzionamento del<strong>la</strong> pipeline del<strong>la</strong> microarchitettura <strong>Intel</strong> ®<br />

Nehalem [24] ................................................................................................... 168<br />

9


10 In<strong>di</strong>ce delle figure<br />

Figura 5.29 - Front end del<strong>la</strong> pipeline del<strong>la</strong> microarchitettura Nehalem [24] . 170<br />

Figura 5.30- Bypass De<strong>la</strong>y tra µ-ops espresso in cicli [24] ............................. 172<br />

Figura 5.31 - Issue Ports del<strong>la</strong> microarchietettura Nehalem [24] .................... 173<br />

Figura 5.32- BTB del Pentium. ........................................................................ 176<br />

Figura 5.33 - Loghi <strong>dei</strong> <strong>processori</strong> <strong>Intel</strong>® Itanium® ed Itanium®2 ................ 181<br />

Figura 5.34 - Due copie dell' "Architectural State" consentono ai <strong>processori</strong> con<br />

tecnologia HyperThrea<strong>di</strong>ng <strong>di</strong> essere visti come 2 <strong>processori</strong> logici [25]. ...... 183<br />

Figura 5.35 – L’ <strong>Intel</strong> ® Pentium ® 4 e le risorse del processore visibili che<br />

vengono dulicate per supportare <strong>la</strong> tecnologia HyperThrea<strong>di</strong>ng. .................... 185<br />

Figura 5.36 – In questa vista del<strong>la</strong> execution pipeline del<strong>la</strong> microarchitettura<br />

NetBurst, le aree chiare e scure in<strong>di</strong>cano l’utilizzo delle risorse <strong>di</strong> due threads<br />

avviate sui due <strong>processori</strong> logici [25]. ............................................................. 188<br />

Figura 5.37 – Con<strong>di</strong>visione delle risorse in alcune CPU <strong>Intel</strong> Multicore ........ 190<br />

Figura 5.38 – Approccio Post-CISC [15] ........................................................ 196<br />

Figura 5.39 - Estensioni dell'Instruction set nei <strong>processori</strong> <strong>Intel</strong> ® [27] ............ 197<br />

Figura 5.40 - MMX ed SSE a confronto[29] ................................................... 199<br />

Figura 5.41: TDP <strong>dei</strong> principali <strong>processori</strong> <strong>Intel</strong> ® per desktop dal Pentium ® II al<br />

Pentium ® D ....................................................................................................... 205<br />

Figura 5.42 : TDP vs Frequenza <strong>di</strong> clock ........................................................ 206<br />

Figura 6.1 - Introduzione del "Loop Stream Detector" .................................... 211<br />

Figura 6.2 - Schema a blocchi <strong>dei</strong> livelli <strong>di</strong> cache nei Core i7. ....................... 215<br />

Figura 6.3 - Schema <strong>di</strong> base del funzionamento in Turbo Mode nel caso <strong>di</strong><br />

alcuni core <strong>di</strong>sattivati. ...................................................................................... 220<br />

Figura 6.4 - Schema <strong>di</strong> base del funzionamento in Turbo Mode nel caso <strong>di</strong> tutti<br />

i core attivi. ...................................................................................................... 221<br />

Figura 6.5 - Power Contro Unit del<strong>la</strong> CPU Core i7.<br />

Figura 7.1 – Fixed-Size Speedup <strong>di</strong> una architettura multicore.[37] ............... 230<br />

221


Figura 7.2 - Fixed-Time Speedup <strong>di</strong> una architettura multicore [37] .............. 230<br />

Figura 7.3 - Memory-Bounded Speedup <strong>di</strong> una architettura multicore [37] .... 231<br />

Figura 7.4 - L’incremento <strong>di</strong> prestazioni RISC ............................................... 235<br />

Figura 7.5 - “A view from Berkeley”: sette punti fondamentali per il calcolo<br />

parallelo del 21° secolo. ................................................................................... 236<br />

Figura 7.6 – <strong>Intel</strong> RMS. ................................................................................... 239<br />

Figura 7.7 - Mapping of EEMBC, SPEC2006, Machine Learning,<br />

Graphcs/Games, Data Base, and <strong>Intel</strong> ® ’s RMS to the 13 Dwarfs. ................... 243<br />

Figura 7.8 – Prestazioni dell’Itanium 2 nel<strong>la</strong> ricerca in matrici sparse<br />

memorizzate me<strong>di</strong>ante tecnica a blocchi [4] .................................................... 244<br />

Figura 7.9 – Dimensione <strong>dei</strong> Blocchi ottimizzate per <strong>di</strong>verse CPU nel<strong>la</strong> ricerca<br />

in matrici sparse [4] ......................................................................................... 245<br />

11


Ringraziamenti<br />

Un bacio a mia moglie Francesca, per avermi supportato in questi anni e in<br />

modo partico<strong>la</strong>re in questi ultimi giorni.<br />

Un grazie speciale a Robby, per i preziosi consigli dati in questi giorni.<br />

Infine, ma non per ultimo, un sentito ringraziamento a tutti coloro che hanno<br />

aspettato da tempo questa tesi e che si sono adoperati perché si potesse<br />

realizzare.


Capitolo 1<br />

Introduzione<br />

Uno degli aspetti più sorprendenti del<strong>la</strong> rivoluzione elettronica nei calco<strong>la</strong>tori è<br />

costituito dallo straor<strong>di</strong>nario progresso che ha caratterizzato i <strong>di</strong>spositivi<br />

elettronici in termini <strong>di</strong> velocità, affidabilità, miniaturizzazione. Anche le<br />

<strong>evoluzioni</strong> delle CPU sono sempre state guidate dal<strong>la</strong> necessità, talvolta più<br />

commerciali che tecnologiche, <strong>di</strong> migliorare determinate prestazioni in termini<br />

<strong>di</strong> velocità, area, consumo, numero <strong>di</strong> componenti, tolleranza ai guasti, tempi <strong>di</strong><br />

realizzazione, ecc...<br />

L’obiettivo storico perseguito dai produttori <strong>di</strong> micro<strong>processori</strong> è sicuramente<br />

quello del miglioramento delle prestazioni sia come capacità <strong>di</strong> calcolo che<br />

come velocità <strong>di</strong> presentazione <strong>dei</strong> risultati dell’e<strong>la</strong>borazione all’utente.<br />

Diverse sono state le strade per poter ottenere questi risultati. In partico<strong>la</strong>re ci<br />

sembra <strong>di</strong> poter in<strong>di</strong>viduare due approcci: uno tecnologico ed uno architetturale.<br />

Possiamo <strong>di</strong>re che da parecchi anni il miglioramento tecnologico segue <strong>la</strong><br />

famosa <strong>legge</strong> <strong>di</strong> <strong>Moore</strong>, in<strong>di</strong>viduando un trend <strong>di</strong> crescita continuo.<br />

Osserviamo ora <strong>la</strong> Figura 1.1 che ci illustra i bound delle prestazioni ottenibili<br />

nelle varie <strong>evoluzioni</strong> tecnologiche legati all’incremento del<strong>la</strong> velocità <strong>di</strong> clock<br />

ed al miglioramento delle architetture.<br />

Dal<strong>la</strong> figura è evidente come, nel<strong>la</strong> ricerca del miglioramento delle prestazioni,<br />

risulta importante il miglioramento tecnologico (rappresentato dall’aumento


16 Capitolo 1<br />

del<strong>la</strong> frequenza <strong>di</strong> clock); allo stesso tempo rileviamo come il perfezionamento<br />

del<strong>la</strong> architettura contribuisca in maniera sempre più considerevole col passare<br />

degli anni.<br />

Figura 1.1 - Incremento delle prestazioni a seguito <strong>di</strong> miglioramenti tecnologici e<br />

<strong>architetturali</strong>.<br />

L’aspetto tecnologico è forse quello che da un punto <strong>di</strong> vista commerciale è<br />

sempre stato maggiormente pubblicizzato e probabilmente fino ad una decina <strong>di</strong><br />

anni fa è stato sicuramente molto importante. Si pensi ad esempio al<strong>la</strong> “corsa al<br />

Gigahertz” che si è avuta fino ai primi anni 2000.


Introduzione 17<br />

Nuovi problemi sempre più stringenti come quello energetico, contribuiscono<br />

al<strong>la</strong> necessità <strong>di</strong> progettare nuove architetture per ottenere significativi<br />

incrementi <strong>di</strong> prestazioni<br />

Questa tesi si propone <strong>di</strong> analizzare le linee guida che hanno accompagnato<br />

negli ultimi 15 anni lo sviluppo delle microarchitetture delle CPU destinate al<br />

mondo <strong>dei</strong> personal computer per cercare <strong>di</strong> capire i prossimi spazi <strong>di</strong> sviluppo.<br />

Dopo una introduzione sulle modalità <strong>di</strong> calcolo delle prestazioni, nel Capitolo<br />

3 vengono presentate da un punto <strong>di</strong> vista concettuale gli elementi <strong>architetturali</strong><br />

che sono al<strong>la</strong> base delle moderne CPU, specialmente per quanto concerne le<br />

prestazioni con qualche accenno a quanto riguarda il risparmio energetico.<br />

Il Capitolo 5e il Capitolo 6 presentano le reali applicazioni <strong>di</strong> tali concetti<br />

adottati dal<strong>la</strong> <strong>Intel</strong> ® Corporation, uno <strong>dei</strong> maggiori produttori <strong>di</strong> CPU,<br />

analizzando le modalità <strong>di</strong> applicazione nelle varie generazioni introdotte sul<br />

mercato a partire dal Pentium ® fino ad arrivare all’ultima microarchitettura<br />

Nehalem.<br />

Al<strong>la</strong> luce <strong>di</strong> quanto illustrato, nel Capitolo 7sono infine proposte alcune<br />

riflessioni che stanno guidando <strong>la</strong> ricerca scientifica nel settore e che<br />

probabilmente troveranno spazio nelle future generazioni <strong>di</strong> <strong>processori</strong>.


Capitolo 2<br />

Il calcolo delle prestazioni<br />

Valutare le prestazioni <strong>di</strong> un sistema <strong>di</strong> e<strong>la</strong>borazione è un compito arduo: le<br />

<strong>di</strong>mensioni e le complessità <strong>dei</strong> moderni sistemi software, unite all’ampia<br />

varietà delle tecniche <strong>di</strong> ottimizzazione delle prestazioni utilizzate dai progettisti<br />

hardware, hanno reso tale valutazione estremamente <strong>di</strong>fficile. Non basta più<br />

conoscere il set <strong>di</strong> istruzioni <strong>di</strong> una macchina, avere a <strong>di</strong>sposizione un insieme<br />

significativo <strong>di</strong> applicazioni software e misurare <strong>la</strong> velocità con cui vengono<br />

eseguite le applicazioni su quel<strong>la</strong> macchina; infatti devono essere utilizzate<br />

metriche <strong>di</strong> misura <strong>di</strong>versa a seconda del tipo <strong>di</strong> applicazione e aspetti <strong>di</strong>fferenti<br />

del sistema <strong>di</strong> calcolo possono essere <strong>di</strong> volta in volta quelli più significativi per<br />

valutare le prestazioni globali. A tal riguardo si pensi ad esempio ai sistemi <strong>di</strong><br />

e<strong>la</strong>borazione portatili dove occorre valutare sia prestazioni in termini <strong>di</strong> velocità<br />

che <strong>di</strong> risparmio energetico.<br />

In questo <strong>la</strong>voro ci soffermeremo in modo partico<strong>la</strong>re su due metriche: le<br />

prestazioni in termini <strong>di</strong> velocità e <strong>di</strong> consumo.<br />

2.1 Prestazioni in termini <strong>di</strong> Velocità<br />

La misura delle prestazioni <strong>di</strong> un calco<strong>la</strong>tore in termini <strong>di</strong> velocità è<br />

normalmente ottenuta me<strong>di</strong>ante stime <strong>di</strong> tempi <strong>di</strong> e<strong>la</strong>borazione.<br />

Quantitativamente, possiamo definire:


20 Capitolo 2<br />

1. Tempo <strong>di</strong> Esecuzione del<strong>la</strong> CPU ( T exec ) o Tempo <strong>di</strong> CPU: tempo<br />

realmente necessario al<strong>la</strong> CPU nel<strong>la</strong> computazione <strong>di</strong> un Task specifico<br />

(spesso misurato in cicli <strong>di</strong> clock).<br />

2. Throughput ( T h ) o <strong>la</strong>rghezza <strong>di</strong> banda: quantità <strong>di</strong> istruzioni o <strong>di</strong><br />

operazioni eseguite nell’unità <strong>di</strong> tempo. Quest’ultimo, essendo una<br />

misura <strong>di</strong> frequenza, si riesce a stimare solo per sequenze <strong>di</strong> operazioni.<br />

Per capire meglio il significato e <strong>la</strong> <strong>di</strong>fferenza <strong>dei</strong> due approcci facciamo<br />

qualche considerazione.<br />

Se tutte le operazioni eseguite da un calco<strong>la</strong>tore sono perfettamente sequenziali<br />

allora possiamo definire il tempo <strong>di</strong> esecuzione come<br />

T<br />

1<br />

=<br />

T<br />

exec (2.1)<br />

h<br />

Se il calco<strong>la</strong>tore può eseguire alcune operazioni in parallelo allora<br />

T<br />

exec<br />

1<br />

> (2.2)<br />

T<br />

h<br />

Ad esempio nelle CPU attuali N operazioni non sono eseguite in un tempo pari<br />

a N volte il tempo per l’esecuzione <strong>di</strong> una istruzione perché fasi <strong>di</strong> esecuzioni <strong>di</strong><br />

una istruzione sono sovrapposte nelle pipeline a fasi <strong>di</strong> esecuzione <strong>di</strong> una<br />

istruzione successiva. Mentre una istruzione viene letta, l’altra viene<br />

deco<strong>di</strong>ficata e così via. In questo modo <strong>la</strong> <strong>la</strong>tenza o T exec per eseguire una<br />

singo<strong>la</strong> istruzione non cambia, ma il throughput T h aumenta.


Il calcolo delle prestazioni 21<br />

Se tra una istruzione e <strong>la</strong> successiva esiste un ritardo non nullo allora si può<br />

anche avere il caso <strong>di</strong><br />

T<br />

exec<br />

1<br />

< (2.3)<br />

T<br />

h<br />

Per esempio molte memorie, se devono cambiare modalità tra lettura e scrittura,<br />

introducono un piccolo ritardo per riportare i registri interni allo stato iniziale.<br />

In questo caso N operazioni <strong>di</strong> memoria hanno un throughput più basso se sono<br />

<strong>di</strong> lettura e scrittura rispetto a quello che si avrebbe con operazioni dello stesso<br />

tipo. In questo caso le memorie hanno ottimizzato l’accesso singolo e <strong>la</strong> <strong>la</strong>tenza<br />

a <strong>di</strong>scapito del throughput.<br />

Esistono alcuni modelli analitici che permettono <strong>di</strong> stimare a priori le<br />

prestazioni delle CPU, seppure nelle ipotesi <strong>di</strong> situazioni ideali. Il modello più<br />

semplice per le prestazioni del<strong>la</strong> CPU utilizza il concetto <strong>di</strong> CPI (Clock Per<br />

Instruction).<br />

Chiamando<br />

Ncc : numero <strong>di</strong> cicli <strong>di</strong> clock.<br />

NI : numero <strong>di</strong> istruzioni in un programma in linguaggio<br />

macchina.<br />

Il CPI me<strong>di</strong>o è definito come:<br />

N<br />

=<br />

NI<br />

CPI cc (2.4)


22 Capitolo 2<br />

Per calco<strong>la</strong>re a priori il CPI me<strong>di</strong>o bisogna conoscere il CPIi dell’istruzione i-<br />

esima e l’occorrenza me<strong>di</strong>a (in percentuale) dell’istruzione i-esima in un<br />

programma (in<strong>di</strong>cata con xi). Tali quantità sono note spesso dai manuali<br />

dell’hardware in esame. Quin<strong>di</strong>:<br />

2.1.1 Tcpu<br />

= ∑ ( i ∗ i)<br />

CPI x CPI (2.5)<br />

DEFINIZIONE E FORMULAZIONE ANALITICA<br />

Chiamando Tck il tempo <strong>di</strong> clock, reciproco del<strong>la</strong> frequenza f <strong>di</strong> <strong>la</strong>voro,<br />

possiamo definire il tempo <strong>di</strong> CPU con una semplice equazione:<br />

T = N * T<br />

(2.6)<br />

cpu<br />

cc<br />

ck<br />

Questa equazione ci da una prima in<strong>di</strong>cazione <strong>di</strong> come le prestazioni <strong>di</strong>pendano<br />

sia dal<strong>la</strong> frequenza <strong>di</strong> <strong>la</strong>voro del<strong>la</strong> cpu, che dal numero <strong>di</strong> cicli <strong>di</strong> necessari per<br />

poter eseguire il programma.<br />

Ma questo numero <strong>di</strong> cicli è sicuramente <strong>di</strong>pendente dal numero <strong>di</strong> istruzioni<br />

presenti nel programma stesso. Se ripren<strong>di</strong>amo il concetto del CPI possiamo<br />

esprimere il tempo <strong>di</strong> CPU come:<br />

T = NI*<br />

CPI * T<br />

(2.7)<br />

cpu<br />

ck<br />

L’equazione (2.7) è nota come <strong>legge</strong> <strong>di</strong> Iron. Da questa possiamo definire<br />

l’unità <strong>di</strong> misura del Tcpu:<br />

⎡ Sec ⎤ ⎛ NI ⎞ ⎛ Ciclo ⎞ ⎛ Sec ⎞<br />

⎢ ⎥ = ⎜ ⎟*<br />

⎜ ⎟*<br />

⎜ ⎟<br />

⎣Prog<br />

⎦ ⎝ Prog ⎠ ⎝ NI ⎠ ⎝ Ciclo ⎠<br />

T cpu (2.8)


Il calcolo delle prestazioni 23<br />

CONSIDERAZIONI QUALITATIVE<br />

L’espressione appena trovata ci evidenzia come Il tempo <strong>di</strong> CPU <strong>di</strong>pende da<br />

tre elementi fondamentali:<br />

• NI: <strong>di</strong>pende dal repertorio <strong>di</strong> istruzioni (ISA), dal grado <strong>di</strong><br />

ottimizzazione del compi<strong>la</strong>tore nonché dal programmatore.<br />

Siccome è il compi<strong>la</strong>tore che traduce le istruzioni in un linguaggio <strong>di</strong><br />

alto livello in istruzioni eseguibili, esso può determinare prestazioni<br />

<strong>di</strong>verse. Compi<strong>la</strong>tori <strong>di</strong>versi possono dare luogo a NI <strong>di</strong>versi, così come<br />

uno stesso compi<strong>la</strong>tore che genera co<strong>di</strong>ce per due macchine <strong>di</strong>verse,<br />

darà NI <strong>di</strong>versi. Il ruolo del compi<strong>la</strong>tore è importantissimo; per progetti<br />

complessi è necessario utilizzare compi<strong>la</strong>tori ottimizzati per il<br />

calco<strong>la</strong>tore specifico che siano in grado <strong>di</strong> sfruttare anche le scelte<br />

micro<strong>architetturali</strong>.<br />

Anche il programmatore stesso ha un ruolo importante nel<strong>la</strong><br />

determinazione <strong>di</strong> questo parametro in fase <strong>di</strong> stesura del co<strong>di</strong>ce.<br />

• CPI: per ogni istruzione <strong>di</strong>pende dal<strong>la</strong> microarchitettura, dal repertorio<br />

delle istruzioni e dal<strong>la</strong> architettura <strong>di</strong> tutto il calco<strong>la</strong>tore (si pensi ad<br />

esempio alle operazioni <strong>di</strong> memoria).<br />

Molto spesso il CPI per istruzione risulta molto variabile (es. istruzioni<br />

tra registi o istruzioni con uso <strong>di</strong> memoria).<br />

Istruzioni semplici richiedono un minor numero <strong>di</strong> cicli. Un<br />

compi<strong>la</strong>tore ottimizzato sceglie istruzioni semplici o con CPI minore;<br />

inoltre attraverso tecniche come <strong>la</strong> pipeline è possibile portare il CPI ad


24 Capitolo 2<br />

un valore molto vicino ad 1. L’aggiunta <strong>di</strong> più unità <strong>di</strong> esecuzione in<br />

parallelo (macchine supersca<strong>la</strong>ri) permette <strong>di</strong> rendere il CPI minore <strong>di</strong><br />

1. Nei calco<strong>la</strong>tori attuali si par<strong>la</strong> infatti <strong>di</strong> IPC (Instruction per Clock),<br />

reciproco del CPI. Ora il parametro IPC nei <strong>processori</strong> <strong>di</strong> recente<br />

generazione è <strong>di</strong> 3,4.<br />

• Tck (o il suo inverso, <strong>la</strong> frequenza): è legato al<strong>la</strong> tecnologia e<br />

all’organizzazione architetturale del<strong>la</strong> CPU.<br />

Oggi grandezze nell’or<strong>di</strong>ne <strong>dei</strong> 3 GHz sono <strong>la</strong> norma per PC; i<br />

microcontrollori invece hanno una frequenza operativa molto più bassa.<br />

Istruzioni complesse richiedono <strong>di</strong> norma frequenze più basse, invece i<br />

calco<strong>la</strong>tori con un repertorio <strong>di</strong> istruzioni più semplice possono operare<br />

a frequenze maggiori. In pc industriali, microcontrollori e DSP per<br />

contenere i costi si usano frequenze ridotte.<br />

Il confronto <strong>di</strong> prestazioni <strong>di</strong> CPU <strong>di</strong>verse deve perciò tenere in considerazione<br />

entrambi questi aspetti e non uno solo <strong>di</strong> essi.<br />

2.1.2 MIPS<br />

DEFINIZIONE E FORMULAZIONE ANALITICA<br />

Una grandezza utilizzata come misura delle prestazioni, in partico<strong>la</strong>re in campo<br />

commerciale, è il MIPS (Mega instruction per second).<br />

Esso è definito come:


Il calcolo delle prestazioni 25<br />

inoltre:<br />

NI<br />

* 10<br />

MIPS =<br />

6<br />

Tcpu<br />

f<br />

=<br />

CPI<br />

MIPS ck<br />

[ MHz]<br />

me<strong>di</strong>o<br />

CONSIDERAZIONI QUALITATIVE<br />

(2.9)<br />

(2.10)<br />

Siccome i MIPS sono una misura delle istruzioni eseguite, fissano le prestazioni<br />

in modo inverso rispetto al tempo <strong>di</strong> CPU: le macchine più veloci hanno un<br />

valore più elevato in termini <strong>di</strong> MIPS.<br />

L’utilizzo <strong>dei</strong> MIPS per il confronto <strong>di</strong> prestazioni, presenta però tre problemi.<br />

Per prima cosa esso specifica una misura delle istruzioni eseguite ma non tiene<br />

conto delle caratteristiche delle istruzioni stesse: si tratta perciò <strong>di</strong> una misura<br />

utilizzabile solo per CPU con <strong>la</strong> stessa ISA, in quanto set <strong>di</strong> istruzioni <strong>di</strong>verse<br />

darebbero luogo a conteggi <strong>di</strong> istruzioni ovviamente <strong>di</strong>fferenti.<br />

In secondo luogo, nello stesso calco<strong>la</strong>tore i MIPS variano a seconda del<br />

programma. Una stessa macchina non ha un unico valore <strong>di</strong> MIPS per ogni<br />

software.<br />

Infine, il punto più importante è che MIPS possono variare in modo inverso<br />

rispetto alle prestazioni.<br />

A titolo <strong>di</strong> esempio, nelle figure seguenti sono riportati i valori MIPS delle CPU<br />

<strong>Intel</strong> ® dal’8086 fino al Pentium ® .


26 Capitolo 2<br />

Figura 2.1 - Grafico delle prestazioni in MIPS delle CPU <strong>Intel</strong> ® dall'8086 al Pentium ®<br />

2.2 Prestazioni in termini <strong>di</strong> Consumo (potenza ed efficienza<br />

energetica)<br />

Il consumo <strong>di</strong> energia elettrica in un qualsiasi circuito integrato è<br />

fondamentalmente dovuto a due processi: una parte viene <strong>di</strong>ssipata nel<strong>la</strong><br />

commutazione <strong>dei</strong> <strong>di</strong>spositivi contenuti nel<strong>la</strong> CPU stessa (es. transistor), mentre<br />

l’altra viene persa sotto forma <strong>di</strong> calore a causa del<strong>la</strong> resistività <strong>dei</strong> circuiti<br />

elettrici.<br />

I produttori <strong>di</strong> <strong>processori</strong> utilizzano normalmente due grandezze per misurare <strong>la</strong><br />

potenza <strong>di</strong>ssipata: <strong>la</strong> “Typical Thermal Power” (TTP) che viene misurata in<br />

normali con<strong>di</strong>zioni <strong>di</strong> carico e <strong>la</strong> “Maximum Thermal Power” (MTP) che viene<br />

misurata facendo eseguire una serie <strong>di</strong> istruzioni complessa.<br />

La <strong>di</strong>ssipazione termica in termini da calore, impone che alle CPU vengano<br />

applicati sistemi <strong>di</strong> raffreddamento tali da garantire temperature <strong>di</strong> esercizio<br />

entro determinati range. La grandezza che viene utilizzata per in<strong>di</strong>care <strong>la</strong>


Il calcolo delle prestazioni 27<br />

quantità <strong>di</strong> energia massima che deve essere in grado <strong>di</strong> <strong>di</strong>ssipare il sistema <strong>di</strong><br />

raffreddamento è il “Thermal Design Power” (TDP), a volte chiamata<br />

“Thermal Design Point”.<br />

L’aumento <strong>dei</strong> costi per l’energia, <strong>la</strong> <strong>di</strong>sponibilità e l’impatto ambientale del<strong>la</strong><br />

produzione energia elettrica, ha portato a considerare l’efficienza energetica<br />

come un parametro molto importante nel<strong>la</strong> valutazione delle prestazioni <strong>dei</strong><br />

calco<strong>la</strong>tori. Se in un primo momento l’interesse maggiore veniva del settore<br />

enterprise per l’ottimizzazione delle sale server, oggi anche nel settore <strong>dei</strong><br />

personal computer l’interesse a<strong>la</strong> efficienza energetica è <strong>di</strong>ventato elevato.<br />

Possiamo <strong>di</strong>re che i PC hanno cambiato il mondo, consentendo alle persone <strong>di</strong><br />

<strong>la</strong>vorare e giocare in mo<strong>di</strong> che precedentemente erano inimmaginabili. Ma<br />

l’elevato numero <strong>di</strong> PC desktop e notebook, hanno ora un effetto misurabile sul<br />

consumo energetico mon<strong>di</strong>ale .<br />

Tutti i produttori sono sempre più attenti a questi aspetti, cercando <strong>di</strong> sviluppare<br />

nuovi prodotti in grado <strong>di</strong> aumentare le prestazioni in termini <strong>di</strong> velocità e<br />

migliorando allo stesso tempo l’efficienza energetica.<br />

Ad oggi non sono ancora definiti degli standard metodologici per una<br />

valutazione congiunta <strong>di</strong> prestazioni e costi energetici associati, anche se i vari<br />

produttori stanno proponendo alcune possibili soluzioni. Ad esempio <strong>Intel</strong> ®<br />

chiama il suo approccio EEP: Energy-Efficient Performance[1][2].


28 Capitolo 2<br />

2.3 Possibili approcci per l’aumento delle prestazioni<br />

Ogni giorno sono progettate soluzioni migliori in termini <strong>di</strong> funzionalità<br />

eseguite e a parità <strong>di</strong> funzionalità, in termini <strong>di</strong> velocità.<br />

Il miglioramento del<strong>la</strong> tecnologia microelettronica è sicuramente una delle<br />

cause <strong>di</strong> questi risultati come ci ricorda <strong>la</strong> famosa <strong>legge</strong> <strong>di</strong> <strong>Moore</strong>:<br />

“Il numero <strong>di</strong> transistor raddoppia ogni 18 mesi, e quin<strong>di</strong> con esso<br />

aumentano le risorse a <strong>di</strong>sposizione”[3]<br />

Come abbiamo potuto osservare nel capitolo precedente, le prestazioni però non<br />

sono <strong>di</strong>rettamente proporzionali né al solo numero <strong>di</strong> transistor, né al<strong>la</strong> so<strong>la</strong><br />

velocità del clock.<br />

Un aspetto almeno altrettanto importante è il miglioramento dell’architettura<br />

<strong>dei</strong> calco<strong>la</strong>tori.<br />

“Non esiste nessuna <strong>legge</strong> esatta, ma dal<strong>la</strong> fine degli anni ‘80 con<br />

l’avvento dell’architettura RISC si è verificato un aumento delle<br />

prestazioni che è passato dal 35% a più del 50% ogni anno.” [4]<br />

Nel<strong>la</strong> Figura 2.2, è riportato un esempio <strong>di</strong> come ad<strong>di</strong>rittura il miglioramento<br />

dell’architettura influenza più del miglioramento del<strong>la</strong> frequenza <strong>di</strong> clock o del<br />

numero <strong>di</strong> transistor;


Il calcolo delle prestazioni 29<br />

Figura 2.2 - Confronto tra <strong>la</strong> <strong>legge</strong> <strong>di</strong> <strong>Moore</strong> e l’incremento delle prestazioni 1<br />

Sebbene storicamente non sia sempre stato così, esistono oggi <strong>di</strong>versi limiti<br />

fisici che fanno pensare a come l’influenza del<strong>la</strong> tecnologia possa nel futuro<br />

essere sempre meno influente nell’aumento delle prestazioni, mentre gli aspetti<br />

<strong>architetturali</strong> siano sempre più <strong>di</strong> cruciale importanza.<br />

2.3.1 Uno sguardo all’evoluzione tecnologica<br />

Nell’aprile del 1965 Gordon <strong>Moore</strong>, che assieme a Robert Noyce e Andy<br />

Groove nel 1968 fondò l’ <strong>Intel</strong> ® , in un articolo sul<strong>la</strong> rivista Electronics 2<br />

ipotizzo<br />

1 Nel<strong>la</strong> figura viene utilizzata come unità <strong>di</strong> misura delle prestazioni <strong>la</strong> GFLOPS: si<br />

tratta dell’acronimo <strong>di</strong> “Giga FLoating point Operation Per Second” ovvero l’analogo<br />

<strong>dei</strong> MIPS ma riferito ad operazioni floating point.


30 Capitolo 2<br />

che l’incremento del<strong>la</strong> capacita e<strong>la</strong>borativa sarebbe continuato per tutti gli anni<br />

Settanta al ritmo <strong>di</strong> un raddoppio ogni 12 mesi[5]. <strong>Moore</strong> aveva appena finito <strong>di</strong><br />

realizzare un chip contenente 60 transistori, il doppio <strong>di</strong> quello che aveva<br />

realizzato l’anno precedente. Per “aumento del<strong>la</strong> capacita e<strong>la</strong>borativa” egli, in<br />

realtà, intendeva “aumento del numero <strong>di</strong> transistori” nel singolo chip. Vedremo<br />

che le due cose non sono perfettamente equivalenti.<br />

Figura 2.3 – Grafico originale <strong>di</strong> Gordon <strong>Moore</strong> del 1965[6].<br />

Questa previsione fu poi corretta dallo stesso <strong>Moore</strong> due volte: nel 1975<br />

portando<strong>la</strong> a un raddoppio ogni 2 anni [7] (ed estendendone <strong>la</strong> vali<strong>di</strong>tà agli anni<br />

Ottanta) e a fine anni Ottanta portando<strong>la</strong> a 18 mesi.<br />

La previsione <strong>di</strong> <strong>Moore</strong>, rive<strong>la</strong>tasi corretta per un periodo molto lungo, e<br />

<strong>di</strong>ventata il metro <strong>di</strong> misura e l’obiettivo per le aziende che operano nel settore,<br />

tanto da essere percepita come una <strong>legge</strong>, <strong>la</strong> cosiddetta <strong>legge</strong> <strong>di</strong> <strong>Moore</strong>.<br />

2 All'epoca era una rivista <strong>di</strong> <strong>la</strong>rghissima <strong>di</strong>ffusione. Veniva <strong>di</strong>stribuita gratis, anche in Italia, a<br />

chiunque fosse ritenuto un soggetto capace <strong>di</strong> influenzare acquisti <strong>di</strong> componenti o apparati<br />

elettronici.


Il calcolo delle prestazioni 31<br />

Come e facile immaginare, più <strong>di</strong> uno scettico ha levato <strong>la</strong> sua voce contra <strong>la</strong><br />

sostenibilità dell’evoluzione quantitativa prevista da questa <strong>legge</strong>. Non c’e<br />

alcuna ragione per cui essa debba continuare a valere: non e una <strong>legge</strong> <strong>di</strong> natura,<br />

bensì una <strong>legge</strong> sull’ingegno umano. Prima o poi smetterà <strong>di</strong> valere. Ma gli<br />

scettici avranno dovuto aspettare un bel po’ prima <strong>di</strong> vedere confermate le loro<br />

critiche 3<br />

.<br />

La <strong>legge</strong> <strong>di</strong> <strong>Moore</strong> spiega in termini quantitativi, meglio <strong>di</strong> qualunque<br />

argomentazione verbale, lo spettaco<strong>la</strong>re sviluppo dell’elettronica a cui si sta<br />

assistendo da anni. Affermare che <strong>la</strong> microelettronica raddoppia <strong>la</strong> sua capacita<br />

ogni 18 mesi significa affermare che nei prossimi 18 mesi avremo un<br />

incremento equivalente a quello che si e avuto fino a oggi. Un tale tasso <strong>di</strong><br />

evoluzione comporta delle conseguenze che verrebbe voglia <strong>di</strong> chiamare<br />

fantascientifiche, se esse non fossero parte del<strong>la</strong> vita <strong>di</strong> tutti i giorni.<br />

Anzitutto c’e un’accentuata riduzione <strong>dei</strong> costi nel tempo, in netta<br />

controtendenza rispetto a qualunque produzione industriale. Si capisce perché<br />

un personal computer corrente ha una capacita e<strong>la</strong>borativa qualche centinaio <strong>di</strong><br />

volte superiore a quel<strong>la</strong> <strong>di</strong> un mainframe <strong>di</strong> trent’anni ad<strong>di</strong>etro, nonostante che il<br />

primo costi intorno al migliaio <strong>di</strong> euro, mentre per un mainframe dell’epoca un<br />

miliardo <strong>di</strong> lire (<strong>di</strong> allora) poteva anche non bastare.<br />

3 Per capire i limiti fisici teorici del<strong>la</strong> <strong>legge</strong> <strong>di</strong> <strong>Moore</strong>, cioè quali sono <strong>la</strong> massima potenza<br />

e<strong>la</strong>borativa e <strong>la</strong> massima densità <strong>di</strong> informazioni raggiungibili, si può <strong>legge</strong>re una serie <strong>di</strong> articoli<br />

sul numero del 31 agosto 2000, vol. 406, del<strong>la</strong> rivista Nature (rintracciabile su Internet), in<br />

partico<strong>la</strong>re l'articolo “Ultimate physical limits to computation” <strong>di</strong> Seth Lloyd (pp.1047-1054).


32 Capitolo 2<br />

In Figura 2.4 viene riportato il numero <strong>di</strong> transistori delle principali CPU <strong>Intel</strong> ®<br />

a partire dal 4004 fino al Core 2 Quad. La Figura 2.5 riporta gli stessi dati in<br />

forma <strong>di</strong> <strong>di</strong>agramma.<br />

Figura 2.4 -Aumento del numero <strong>di</strong> transistori delle CPU <strong>Intel</strong> ® . I dati riportati si<br />

riferiscono al modello <strong>di</strong> introduzione sul mercato. Per i modelli introdotti in più<br />

versioni, <strong>la</strong> tabel<strong>la</strong> riporta i dati re<strong>la</strong>tivi al<strong>la</strong> versione <strong>di</strong> più bassa capacità. Per<br />

esempio il Pentium ® Pro è stato introdotto in ben quattro versioni, <strong>di</strong> cui <strong>la</strong> meno<br />

potente (quel<strong>la</strong> riportata) era tecnologia a 0,6µm e frequenza pari a 150MHz, mentre <strong>la</strong><br />

più avanzata era in tecnologia a 0,35 µm e frequenza pari a 200 MHz [8].<br />

L’evoluzione del<strong>la</strong> microelettronica passa sia attraverso <strong>la</strong> progressiva riduzione<br />

delle <strong>di</strong>mensioni <strong>dei</strong> transistori sul chip sia attraverso <strong>la</strong> riduzione delle<br />

<strong>di</strong>mensioni delle connessioni tra <strong>di</strong> essi. La <strong>di</strong>mensione <strong>dei</strong> circuiti <strong>di</strong><br />

connessione e spesso utilizzata come parametro <strong>di</strong> misura. Al<strong>la</strong> data <strong>di</strong><br />

pubblicazione <strong>di</strong> questa tesi (aprile 2009) <strong>la</strong> produzione <strong>di</strong> avanguar<strong>di</strong>a <strong>di</strong> <strong>Intel</strong> ®<br />

è a 45 nm.


Il calcolo delle prestazioni 33<br />

Figura 2.5 – Aumento del numero <strong>di</strong> transistori nelle CPU <strong>Intel</strong> ® [8]<br />

2.3.2 Corsa al gigahertz e il limite <strong>dei</strong> 4 GHz<br />

Sebbene <strong>la</strong> <strong>legge</strong> <strong>di</strong> <strong>Moore</strong> sia ancora rispettata, anche se con qualche<br />

adattamento, possiamo osservare come <strong>la</strong> velocità <strong>di</strong> <strong>la</strong>voro delle CPU abbia<br />

invece subito una brusco rallentamento. Anzi, se consideriamo ad esempio i<br />

primi modelli del successore del Pentium ® 4, sono usciti sul mercato con<br />

frequenze <strong>di</strong> <strong>la</strong>voro molto più basse (1,2 GHz rispetto ai 3,6 delle versioni più<br />

performanti dello stesso P4).<br />

I produttori <strong>di</strong> CPU, fino a questo momento, avevano abituato <strong>la</strong> maggior parte<br />

degli utenti a pensare che il principale parametro prestazione del<strong>la</strong> CPU fosse <strong>la</strong><br />

sua velocità <strong>di</strong> clock; chi si è trovato a dover vendere Personal Computer in<br />

quel periodo ha sicuramente trovato qualche <strong>di</strong>fficoltà a convincere i propri<br />

clienti che, nonostante <strong>la</strong> riduzione <strong>di</strong> frequenza, le prestazioni complessive<br />

erano migliorate.


34 Capitolo 2<br />

Se però ripren<strong>di</strong>amo <strong>la</strong> formu<strong>la</strong> del Tcpu, risulta evidente come questo sia<br />

possibile se vengono migliorati gli altri due aspetti: il set <strong>di</strong> istruzioni e gli<br />

aspetti <strong>architetturali</strong>.<br />

Ma come mai si è stati costretti a ridurre le frequenze <strong>di</strong> <strong>la</strong>voro e non si è<br />

riusciti a mantenere il trend <strong>di</strong> crescita precedente?<br />

Possiamo in<strong>di</strong>viduare tre motivi principali:<br />

• Problemi re<strong>la</strong>tivi al<strong>la</strong> potenza <strong>di</strong>ssipata. l’aumento del<strong>la</strong> frequenza <strong>di</strong><br />

<strong>la</strong>voro del<strong>la</strong> CPU comporta un aumento del numero <strong>di</strong> commutazioni<br />

<strong>dei</strong> transistor e pertanto un aumento del<strong>la</strong> potenza <strong>di</strong>ssipata come<br />

anticipato nel paragrafo 2.2.<br />

La riduzione delle <strong>di</strong>mensioni <strong>dei</strong> transistor con <strong>la</strong> conseguente<br />

riduzione delle tensioni <strong>di</strong> <strong>la</strong>voro, nonché l’esperienza nel<strong>la</strong><br />

progettazione <strong>dei</strong> <strong>la</strong>yout permette <strong>di</strong> ottenere da un punto <strong>di</strong> vista<br />

tecnologico <strong>la</strong> riduzione del consumo <strong>di</strong> energia.<br />

Figura 2.6 - Densità <strong>di</strong> potenza <strong>di</strong>ssipata dalle CPU


Il calcolo delle prestazioni 35<br />

• Problemi termici. L’aspetto più gravoso del<strong>la</strong> <strong>di</strong>ssipazione <strong>di</strong> potenza,<br />

che può implicare anche il cattivo funzionamento del<strong>la</strong> CPU stessa, è <strong>la</strong><br />

<strong>di</strong>ssipazione termica. <strong>Oltre</strong> una certa temperatura infatti i <strong>di</strong>spositivi<br />

integrati perdono le loro capacità funzionali. Si rende pertanto<br />

necessario applicare <strong>di</strong>spositivi <strong>di</strong> <strong>di</strong>ssipazione che garantiscano un<br />

adeguato raffreddamento del chip.<br />

• Il Limite fisico del<strong>la</strong> velocità luce e i problemi <strong>di</strong> propagazione <strong>dei</strong><br />

segnali: senza voler effettuare una trattazione rigorosa sul<strong>la</strong> ricerca <strong>di</strong><br />

quale sia il limite massimo del<strong>la</strong> frequenza <strong>di</strong> clock <strong>di</strong> una CPU,<br />

osserviamo se riuscissimo a fare propagare il segnale per 1 cm al<strong>la</strong><br />

velocità del<strong>la</strong> luce nel vuoto <strong>la</strong> massima frequenza ottenibile sarebbe <strong>di</strong><br />

10GHZ. In realtà le con<strong>di</strong>zioni sono ben <strong>di</strong>fferenti dal vuoto, nonché le<br />

<strong>di</strong>stanze percorse possono essere anche maggiori. In più si presentano<br />

problemi <strong>di</strong> <strong>di</strong>storsione del segnale a causa delle capacità intrinseche<br />

<strong>dei</strong> circuiti.<br />

2.4 Legge <strong>di</strong> Amdahl<br />

Un ulteriore spunto <strong>di</strong> riflessione su come ci si debba muovere per migliorare le<br />

prestazioni <strong>di</strong> una CPU ci viene dal<strong>la</strong> <strong>legge</strong> <strong>di</strong> Amdahl [9].<br />

Questa rego<strong>la</strong> afferma che:<br />

“Se si migliora solo un elemento del calco<strong>la</strong>tore, il miglioramento<br />

complessivo ottenuto <strong>di</strong>pende dal<strong>la</strong> % <strong>di</strong> tempo <strong>di</strong> uso <strong>di</strong> quel<br />

componente”.


36 Capitolo 2<br />

La lettura <strong>di</strong> questa rego<strong>la</strong> per quanto riguarda <strong>la</strong> possibilità <strong>di</strong> incremento delle<br />

prestazioni ci porta a due considerazioni.<br />

In primo luogo concentrarsi a migliorare un solo aspetto <strong>di</strong> un qualsiasi<br />

componente, può ad<strong>di</strong>rittura essere quasi ininfluente in termini <strong>di</strong> prestazioni<br />

del sistema complessivo.<br />

In secondo luogo possiamo desumere il seguente corol<strong>la</strong>rio:<br />

“Per migliorare <strong>la</strong> velocità <strong>di</strong> un sistema conviene aumentare <strong>la</strong> velocità degli<br />

elementi che vengono utilizzati più frequentemente”.<br />

CONSIDERAZIONI ANALITICHE<br />

Cerchiamo ora <strong>di</strong> vedere questi concetti da un punto <strong>di</strong> vista più analitico.<br />

Per un qualsiasi sistema, si può definire una grandezza che in<strong>di</strong>ca quanto è<br />

migliorata <strong>la</strong> prestazione globale del sistema in seguito ad un miglioramento<br />

anche solo <strong>di</strong> una sua parte.<br />

Questa grandezza prende il nome <strong>di</strong> Speedup.<br />

Lo Speedup o accelerazione è pertanto un in<strong>di</strong>ce <strong>di</strong> miglioramento.<br />

In realtà esso altro non è che il rapporto tra <strong>la</strong> prestazione ottenuta con il<br />

miglioramento rispetto a quel<strong>la</strong> ottenuta senza miglioramento.<br />

Dato che nelle CPU il miglioramento cercato è in termini <strong>di</strong> velocità, le<br />

prestazioni sono il reciproco del tempo <strong>di</strong> esecuzione:<br />

SP<br />

new →old<br />

P<br />

=<br />

P<br />

new<br />

old<br />

T<br />

=<br />

T<br />

exec<br />

exec<br />

old<br />

new<br />

(2.11)


Il calcolo delle prestazioni 37<br />

All’utilizzatore però poco importa lo speedup <strong>di</strong> ciascun elemento <strong>di</strong> un<br />

calco<strong>la</strong>tore; è sicuramente molto più interessato a quello che si chiama<br />

“speedup overall” ossia il miglioramento complessivo <strong>di</strong> tutto il calco<strong>la</strong>tore.<br />

Per quantificare lo speedup overall ci viene proprio in aiuto <strong>la</strong> “Legge <strong>di</strong><br />

Amdahl” che possiamo anche riformu<strong>la</strong>re nel modo seguente:<br />

“Il miglioramento delle prestazioni dovute ad un miglioramento <strong>di</strong> esecuzione è<br />

limitato dal<strong>la</strong> frazione <strong>di</strong> tempo in cui tale miglioramento può essere applicato”.<br />

dove:<br />

⎡ F ⎤ enh<br />

exec = T * ( 1 )<br />

new exec ⎢ − F enh + ⎥ (2.12)<br />

⎣ Senh<br />

⎦<br />

T old<br />

Fenh (fraction enhanced): è <strong>la</strong> percentuale <strong>di</strong> tempo in cui ha effetto<br />

il miglioramento<br />

Senh (speedup enhanced) è il valore <strong>di</strong> tale miglioramento.<br />

Dal<strong>la</strong> equazione (2.12) si ottiene che lo speedup complessivo risulta:<br />

SP overall<br />

=<br />

⎡<br />

⎢<br />

⎣<br />

1<br />

( 1−<br />

F )<br />

enh<br />

F<br />

+<br />

S<br />

enh<br />

enh<br />

⎤<br />

⎥<br />

⎦<br />

(2.13)<br />

Per capire meglio in termini quantitativi queste considerazioni facciamo due<br />

esempi.<br />

Supponiamo <strong>di</strong> avere due calco<strong>la</strong>tori identici che montano però due versioni<br />

<strong>di</strong>verse <strong>di</strong> CPU. Il calco<strong>la</strong>tore B monta, per ipotesi, una CPU che è 5 volte più<br />

veloce <strong>di</strong> quello instal<strong>la</strong>ta sul calco<strong>la</strong>tore A. Supponiamo poi che il tempo


38 Capitolo 2<br />

me<strong>di</strong>o <strong>di</strong> utilizzo del<strong>la</strong> CPU da parte degli applicativi sia del 50%. A quanto<br />

ammonta l’incremento effettivo <strong>di</strong> prestazioni tra il calco<strong>la</strong>tore A ed il<br />

Calco<strong>la</strong>tore B?<br />

In questo caso avremo che<br />

Pertanto<br />

S = 5<br />

(2.14)<br />

enh<br />

F = 0,5<br />

(2.15)<br />

enh<br />

SP overall<br />

=<br />

⎡<br />

⎢<br />

⎣<br />

( 1−<br />

0,<br />

5)<br />

1<br />

= 1,66<br />

0,<br />

5⎤<br />

+<br />

5 ⎥<br />

⎦<br />

(2.16)<br />

Confrontiamo ora una scelta architetturale che prevede l’impiego <strong>di</strong> nuove<br />

componenti con speedup elevatissimo (anche <strong>di</strong> 20) ma utilizzate in minima<br />

parte (circa il 10%) rispetto ad una scelta <strong>di</strong> miglioramento più contenuto<br />

(anche solo del 1,2) ad una parte usata il 90% <strong>dei</strong> casi.<br />

In questo caso avremo:<br />

Caso 1 Caso 2<br />

Senh<br />

= 20<br />

SP overall<br />

=<br />

⎡<br />

⎢<br />

⎣<br />

( 1−<br />

0,<br />

5)<br />

Fenh<br />

= 0,1<br />

1<br />

= 1,105<br />

0,<br />

5⎤<br />

+<br />

20 ⎥<br />

⎦<br />

Senh<br />

= 1,2<br />

SP overall<br />

=<br />

⎡<br />

⎢<br />

⎣<br />

( 1−<br />

0,<br />

9)<br />

Fenh<br />

= 0,9<br />

1<br />

= 1,176<br />

0,<br />

9⎤<br />

+<br />

1,<br />

2<br />

⎥<br />

⎦<br />

Figura 2.7 - I risultati mostrano come un incremento anche minimo nelle prestazioni <strong>di</strong><br />

una parte utilizzata per parecchio tempo sia complessivamente più rilevante <strong>di</strong> un<br />

miglioramento importante <strong>di</strong> parti poco utilizzate.


Il calcolo delle prestazioni 39<br />

Nelle macchine RISC si era ad esempio osservato che il 90% del tempo era<br />

utilizzato per eseguire soltanto il 10% delle istruzioni <strong>di</strong>sponibili e quin<strong>di</strong> le<br />

nuove scelte <strong>architetturali</strong> vennero stu<strong>di</strong>ate per migliorare solo quel 10%, anche<br />

a <strong>di</strong>scapito del resto.<br />

L’analisi del<strong>la</strong> espressione analitica del<strong>la</strong> <strong>legge</strong> <strong>di</strong> Amdahl, ci porta anche ad<br />

osservare come esista un limite allo speedup overall, <strong>di</strong>pendente dal<strong>la</strong><br />

percentuale <strong>di</strong> uso <strong>di</strong> una parte del sistema.<br />

Se infatti facciamo tendere ad infinito lo speedup enhanched, lo speedup overall<br />

resta limitato:<br />

SP<br />

lim overall<br />

→∞<br />

S enh<br />

=<br />

1<br />

[ ( 1−<br />

F ) ]<br />

enh<br />

(2.17)


Capitolo 3<br />

Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle<br />

prestazioni<br />

3.1 Introduzione<br />

Ripren<strong>di</strong>amo <strong>la</strong> <strong>legge</strong> <strong>di</strong> Iron (2.7) del tempo <strong>di</strong> CPU:<br />

NI<br />

T cpu = NI * CPI * Tck<br />

= * Tck<br />

(3.1)<br />

IPC<br />

Come già precedentemente accennato, mantenendo costante il tempo <strong>di</strong> clock<br />

Tck, il miglioramento delle prestazioni <strong>di</strong> una CPU si ottengono:<br />

• riducendo NI<br />

• aumentando IPC (Instruction Per Clock)<br />

Ma quali sono gli aspetti <strong>architetturali</strong> che ci permettono <strong>di</strong> ottenere questi<br />

risultati?<br />

Una prima possibilità è quel<strong>la</strong> <strong>di</strong> cercare <strong>di</strong> eseguire un numero maggiore <strong>di</strong><br />

operazioni contemporaneamente, in modo da aumentare IPC; in altri termini<br />

significa aumentare il parallelismo.<br />

L’aumento dell’IPC può anche essere ottenuto cercando <strong>di</strong> ridurre al minimo i<br />

motivi <strong>di</strong> stallo del<strong>la</strong> CPU legati per esempio ad elementi esterni “lenti” (es<br />

memorie).


42 Capitolo 3<br />

Un altro modo per aumentare le prestazioni è indubbiamente legato al numero<br />

<strong>di</strong> istruzioni necessarie. Un modo per ridurre il tempo <strong>di</strong> CPU è perciò quello <strong>di</strong><br />

aggiungere nell’ISA <strong>dei</strong> set <strong>di</strong> istruzioni ottimizzati specializzati all’esecuzione<br />

<strong>di</strong> determinate operazioni.<br />

3.2 Parallelismo<br />

Nel<strong>la</strong> figura seguente sono riportati <strong>di</strong>versi tipi <strong>di</strong> parallelismo applicabili ai<br />

sistemi <strong>di</strong> e<strong>la</strong>borazione:<br />

Figura 3.1 - Diversi tipi <strong>di</strong> parallelismo applicabile ai sistemi <strong>di</strong> e<strong>la</strong>borazione.


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 43<br />

I fattori che caratterizzano, dal punto <strong>di</strong> vista hardware, un sistema parallelo<br />

sono i seguenti:<br />

• Natura e numero degli elementi <strong>di</strong> calcolo: il parallelismo può essere<br />

stabilito tra semplici ALU (anche 1.000.000) oppure tra potenti CPU<br />

complete (fino a 10.000).<br />

• Natura e numero degli elementi <strong>di</strong> memoria: normalmente <strong>la</strong> memoria è<br />

sud<strong>di</strong>visa in moduli in<strong>di</strong>pendenti al fine <strong>di</strong> permettervi l’accesso da più<br />

CPU contemporaneamente.<br />

• Modalità <strong>di</strong> interconnessione: rappresenta il principale elemento <strong>di</strong><br />

<strong>di</strong>fferenziazione. La connessione può essere:<br />

o Statica: i legami tra le CPU sono determinati a priori e sono<br />

fissi<br />

o Dinamica: i legami tra le CPU sono definiti in base alle<br />

necessità da opportuni <strong>di</strong>spositivi (switch) in grado <strong>di</strong> instradare<br />

i messaggi.<br />

Sebbene qualsiasi combinazione <strong>di</strong> queste caratteristiche sia possibile si<br />

tendono a realizzare sistemi con un piccolo numero <strong>di</strong> CPU in<strong>di</strong>pendenti, gran<strong>di</strong><br />

e dotate d’interconnessioni a bassa velocità (sistemi debolmente accoppiati o<br />

loosely coupled) oppure sistemi in cui il parallelismo è realizzato a livello <strong>di</strong><br />

componenti più piccole e che interagiscono fortemente tra loro (sistemi<br />

fortemente accoppiati o strongly coupled).


44 Capitolo 3<br />

Esiste una forte corre<strong>la</strong>zione tra le caratteristiche hardware <strong>di</strong> un sistema<br />

parallelo e i problemi software che possono essere utilmente risolti su <strong>di</strong> esso. Il<br />

fattore <strong>di</strong>scriminante è il livello <strong>di</strong> granu<strong>la</strong>rità del parallelismo:<br />

• Parallelismo course-grained: l’elemento software che viene<br />

parallelizzato è grande (es. programma); i vari processi paralleli non<br />

hanno bisogno <strong>di</strong> comunicare (es. Sistema UNIX multi-utente, web-<br />

server).<br />

• Parallelismo fine-grained: l’elemento software che viene parallelizzato<br />

è piccolo (es. singo<strong>la</strong> operazione); i vari processi paralleli hanno<br />

bisogno <strong>di</strong> comunicare poiché stanno risolvendo lo stesso problema (es.<br />

Calco<strong>la</strong>tori vettoriali).<br />

PARALLELISMO NEL CHIP<br />

L’interesse <strong>di</strong> questo <strong>la</strong>voro è <strong>di</strong> valutare le possibilità <strong>di</strong> incremento delle<br />

prestazioni delle singole CPU. Ci soffermeremo pertanto a trattare il<br />

parallelismo sul singolo chip.<br />

Diverse sono le possibilità <strong>di</strong> implementazione del parallelismo a livello <strong>di</strong><br />

singo<strong>la</strong> CPU:<br />

• Parallelismo a livello <strong>di</strong> istruzioni (ILP – Instruction Level<br />

Parallelism): l’idea che sta al<strong>la</strong> base <strong>di</strong> questo approccio consiste nel<br />

fare eseguire contemporaneamente più istruzioni. Esempi <strong>di</strong> queste<br />

tecniche sono le Pipeline e le Architetture Supersca<strong>la</strong>ri.<br />

• Multi-threa<strong>di</strong>ng: in questo caso <strong>la</strong> CPU esegue contemporaneamente<br />

due thread (parti <strong>di</strong> programma) come se esistessero due CPU virtuali.


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 45<br />

Se uno <strong>dei</strong> due deve attendere, ad esempio per un cache-miss (sia <strong>di</strong><br />

primo che <strong>di</strong> secondo livello), l’altro può continuare l’esecuzione<br />

evitando <strong>di</strong> <strong>la</strong>sciare <strong>la</strong> CPU in attesa. È il caso dell’HyperThrea<strong>di</strong>ng del<br />

Pentium ® 4. In casi limite, il multi-threa<strong>di</strong>ng su CPU virtuali può portare<br />

a peggioramento delle prestazioni.<br />

• Multi-core: consente un vero multi-threa<strong>di</strong>ng e permette in certi casi <strong>di</strong><br />

aumentare notevolmente le prestazioni. Es. Core 2 Duo <strong>di</strong> <strong>Intel</strong> ® .<br />

• Più core eterogenei nel chip: ingloba nello stesso chip due o più core<br />

ma con funzionalità specializzate. Es. Cell <strong>di</strong> IBM/Sony/Toshiba.<br />

3.2.1 Instruction Level Parallelism<br />

L’ “Instruction Level Parallelism” (ILP ovvero parallelismo a livello<br />

d’istruzione) è <strong>la</strong> possibilità <strong>di</strong> eseguire delle istruzioni <strong>di</strong> un programma in<br />

parallelo da parte un sistema <strong>di</strong> calcolo.<br />

La ricerca <strong>di</strong> rendere il co<strong>di</strong>ce parallelo a livello <strong>di</strong> istruzioni è <strong>di</strong>ventata una<br />

priorità nei moderni micro<strong>processori</strong>. Questi ultimi infatti sono dotati <strong>di</strong> molte<br />

unità <strong>di</strong> calcolo e usualmente seguono una struttura a pipeline: l’in<strong>di</strong>viduazione<br />

e lo sfruttamento delle istruzioni eseguibili in parallelo permette pertanto <strong>di</strong><br />

utilizzare le unità funzionali <strong>dei</strong> <strong>processori</strong> contemporaneamente innalzando le<br />

prestazioni del microprocessore.<br />

Consideriamo il seguente frammento <strong>di</strong> pseudoco<strong>di</strong>ce:<br />

Istruzione 1:<br />

h =<br />

a + b


46 Capitolo 3<br />

Istruzione 2:<br />

Istruzione 3:<br />

f = c + d<br />

g = h * f<br />

L’istruzione 1 e 2 possono essere eseguite in parallelo dato che richiedono <strong>dei</strong><br />

dati (a, b, c, d) che non sono utilizzate da altre istruzioni e quin<strong>di</strong> sono libere.<br />

Invece l’istruzione 3, per venire eseguita, deve attendere il completamento delle<br />

prime due istruzioni dato che i dati h e f <strong>di</strong>pendono dall’esecuzione delle prime<br />

due istruzioni. Supponendo <strong>di</strong> avere delle unità <strong>di</strong> calcolo (ALU) in<strong>di</strong>pendenti<br />

quin<strong>di</strong> si possono eseguire le istruzioni 1 e 2 in parallelo mentre <strong>la</strong> 3 deve<br />

attendere le altre due. Supponendo <strong>di</strong> avere unità che eseguono le operazioni in<br />

un ciclo <strong>di</strong> clock eseguendo le operazioni in parallelo si può completare il<br />

co<strong>di</strong>ce in due cicli <strong>di</strong> clock mentre un’esecuzione seriale del co<strong>di</strong>ce<br />

richiederebbe tre cicli <strong>di</strong> clock. Con questa mo<strong>di</strong>fica l’IPC <strong>di</strong>venta 3/2 dato che<br />

si eseguono tre istruzioni in due cicli <strong>di</strong> clock.<br />

CENNI STORICI<br />

Fin dagli albori dell’informatica i progettisti hanno cercato <strong>di</strong> eseguire alcune<br />

operazioni in parallelo al fine <strong>di</strong> ottenere un incremento delle prestazioni <strong>dei</strong><br />

sistemi <strong>di</strong> e<strong>la</strong>borazione. Già lo Z3, il primo computer <strong>di</strong>gitale degli anni 40, era<br />

in grado <strong>di</strong> eseguire alcune parti delle e<strong>la</strong>borazioni in parallelo al fine <strong>di</strong><br />

migliorare le sue prestazioni.<br />

Il suo successore, lo Z4 (1944-1949) provvedeva al caricamento <strong>di</strong> due<br />

istruzioni in parallelo se non vinco<strong>la</strong>te, in modo da ridurre i tempi <strong>di</strong> accesso.


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 47<br />

È del 1946 nei <strong>la</strong>boratori Bell, era stato implementato un gestore <strong>di</strong> due<br />

<strong>processori</strong> venivano gestiti che <strong>di</strong>stribuiva le istruzioni base alle unità libere.<br />

Nell’IBM SSEC (1948), due istruzioni se non <strong>di</strong>pendenti venivano unite in una<br />

so<strong>la</strong> linea in modo da poterle far eseguire in parallelo al computer. Il<br />

trasferimento <strong>dei</strong> dati era effettuato in modo asincrono.<br />

Già nel 1953 un articolo <strong>di</strong> Wilkes e Stinger [10] suggerisce <strong>la</strong> possibilità <strong>di</strong><br />

raccogliere istruzioni in<strong>di</strong>pendenti in una so<strong>la</strong> macroistruzione da far caricare al<br />

computer.<br />

È invece del 1969 articolo sullo sviluppo <strong>di</strong> un primitivo sistema VLIW <strong>di</strong><br />

Melliar-Smith.<br />

Gene Amdahl nel<strong>la</strong> sua tesi del 1951 [9], descrive una pipeline a quattro sta<strong>di</strong><br />

(caricamento istruzione, caricamento dati, esecuzione, salvataggio risultati). Le<br />

pipeline cominceranno ad essere implementate nelle CPU i primi degli anni 60.<br />

Nel 1964 esce il CDC 6600, processore sca<strong>la</strong>re con esecuzione fuori or<strong>di</strong>ne,<br />

dotato <strong>di</strong> <strong>di</strong>eci unità funzionali nel<strong>la</strong> CPU. La CPU deco<strong>di</strong>fica un’istruzione per<br />

ciclo <strong>di</strong> clock e <strong>la</strong> invia allo scoreboard che può avviare fino a tre istruzioni in<br />

contemporanea (limitazione dovuta al<strong>la</strong> presenza <strong>di</strong> registri a trip<strong>la</strong> porta). In<br />

questa CPU compare anche una ru<strong>di</strong>mentale esecuzione multithrea<strong>di</strong>ng.<br />

Nel 1966 Michael J. Flynn presenta sul<strong>la</strong> rivista IEEE un articolo [11] sui<br />

sistemi <strong>di</strong> calcolo ad alta velocità, mettendo le basi per una c<strong>la</strong>ssificazione <strong>dei</strong><br />

sistemi <strong>di</strong> calcolo nota con il nome <strong>di</strong> Tassonomia <strong>di</strong> Flynn (ve<strong>di</strong> Figura 3.2).


48 Capitolo 3<br />

Figura 3.2 - Tassonomia <strong>di</strong> Flynn per <strong>la</strong> c<strong>la</strong>ssificazione <strong>dei</strong> sistemi paralleli<br />

Negli anni settanta e ottanta sono <strong>di</strong>verse le applicazioni <strong>di</strong> architetture<br />

supersca<strong>la</strong>ri e tecniche VLIW.<br />

È dell’ottobre 1981 il brevetto <strong>di</strong> James H. Pomerene (IBM), "Machine for<br />

multiple instruction execution"[12], sul<strong>la</strong> realizzazione <strong>di</strong> sistemi che e<strong>la</strong>borano<br />

gruppi <strong>di</strong> istruzioni in<strong>di</strong>pendenti contemporaneamente.<br />

Nel recente 2001, <strong>Intel</strong> ® presenta i <strong>processori</strong> Itanium basati su architettura<br />

Explicitly Parallel Instruction Computing (EPIC).<br />

TIPOLOGIE DI ILP<br />

Possiamo <strong>di</strong>stinguere due macrocategorie <strong>di</strong> ILP: l’ILP statico e quello<br />

<strong>di</strong>namico.<br />

Nel “ILP statico” il processore riceve le operazioni già sud<strong>di</strong>vise in blocchi <strong>di</strong><br />

istruzioni in<strong>di</strong>pendenti eseguibili in parallelo; il processore deve unicamente


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 49<br />

eseguire le istruzioni dato che l’analisi del co<strong>di</strong>ce è già stata effettuata dal<br />

compi<strong>la</strong>tore, il quale ha già in<strong>di</strong>viduato ed evidenziato le parti eseguibili in<br />

parallelo. Questo approccio permette <strong>di</strong> realizzare <strong>processori</strong> semplici e veloci<br />

ma ha lo svantaggio che i programmi vengono compi<strong>la</strong>ti appositamente per un<br />

singolo tipo <strong>di</strong> processore e mo<strong>di</strong>fiche all’architettura interna del processore<br />

possono produrre notevoli riduzioni <strong>di</strong> prestazioni e in casi estremi anche errori<br />

<strong>di</strong> esecuzione. I <strong>processori</strong> Very Long Instruction Word (VLIW) seguono<br />

questa filosofia.<br />

Invece nel “ILP <strong>di</strong>namico” il compi<strong>la</strong>tore non analizza il co<strong>di</strong>ce al<strong>la</strong> ricerca <strong>di</strong><br />

istruzioni parallelizzabili; questo compito viene infatti svolto dal processore che<br />

durante l’esecuzione decide <strong>di</strong>namicamente quali istruzioni sono eseguibili in<br />

parallelo. Questo permette <strong>di</strong> non legare il co<strong>di</strong>ce all’architettura <strong>di</strong> un singolo<br />

processore ma ha lo svantaggio <strong>di</strong> rendere il microprocessore molto più<br />

complesso e potenzialmente più lento. Il processore ha pochi nanosecon<strong>di</strong> per<br />

decidere se esistono delle istruzioni parallelizzabili e per decidere come<br />

organizzarle mentre un compi<strong>la</strong>tore può fare un’analisi approfon<strong>di</strong>ta del co<strong>di</strong>ce<br />

avendo molto più tempo a <strong>di</strong>sposizione.<br />

I micro<strong>processori</strong> per computer implementano ormai tutti l’ILP <strong>di</strong>namico,<br />

sebbene molti possano utilizzare anche alcune tecniche <strong>di</strong> ILP statico per<br />

incrementare le prestazioni.


50 Capitolo 3<br />

ILP DINAMICO<br />

Durante l’esecuzione il processore per in<strong>di</strong>viduare le istruzioni parallelizzabili<br />

può utilizzare molte tecniche, le principali sono:<br />

La Pipeline<br />

La pipeline è una tecnologia <strong>di</strong> parallelismo ILP utilizzata dai micro<strong>processori</strong><br />

per incrementare il throughput. L’e<strong>la</strong>borazione <strong>di</strong> un’istruzione da parte <strong>di</strong> un<br />

processore si compone <strong>di</strong> cinque passaggi fondamentali:<br />

IF (Instruction fetch): Lettura dell’istruzione da memoria<br />

ID (Instruction decode): Deco<strong>di</strong>fica istruzione e lettura<br />

operan<strong>di</strong> da registri<br />

EX (Execution): Esecuzione dell’istruzione<br />

MEM (Memory access): Accesso al<strong>la</strong> memoria (solo per certe<br />

istruzioni)<br />

WB (Write back): Scrittura del risultato nel registro<br />

opportuno<br />

Figura 3.3 - Passaggi fonfdamentali <strong>di</strong> una pipeline<br />

Senza pipeline <strong>la</strong> CPU richiede quin<strong>di</strong> almeno cinque cicli <strong>di</strong> clock per eseguire<br />

una singo<strong>la</strong> istruzione e l’istruzione successiva non può iniziare fino al<br />

completamento <strong>di</strong> quel<strong>la</strong> precedente.<br />

Figura 3.4- E<strong>la</strong>borazione <strong>di</strong> istruzioni senza pipeline.


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 51<br />

L’esecuzione delle istruzioni con pipeline prevede che <strong>la</strong> CPU sia composta da<br />

<strong>di</strong>versi sta<strong>di</strong> specializzati, capaci <strong>di</strong> eseguire ciascuno una operazione<br />

elementare <strong>di</strong> quelle sopra descritte. La CPU <strong>la</strong>vora come in una catena <strong>di</strong><br />

montaggio e quin<strong>di</strong> ogni sta<strong>di</strong>o provvede a svolgere solo un compito specifico.<br />

Quando <strong>la</strong> catena è a regime, ad ogni ciclo <strong>di</strong> clock esce dall’ultimo sta<strong>di</strong>o<br />

un’istruzione completata. Nello stesso istante ogni unità sta e<strong>la</strong>borando in<br />

parallelo i <strong>di</strong>versi sta<strong>di</strong> delle successive istruzioni. In sostanza si guadagna una<br />

maggior velocità <strong>di</strong> esecuzione a prezzo <strong>di</strong> una maggior complessità circuitale<br />

del microprocessore, che non deve essere più composto da una so<strong>la</strong> unità ma da<br />

cinque unità che devono col<strong>la</strong>borare tra loro.<br />

Cenni storici<br />

Figura 3.5- Esecuzione <strong>di</strong> istruzioni con pipeline<br />

Nel 1951 Gene Amdahl nel<strong>la</strong> sua tesi [9] introduce un nuovo elemento <strong>di</strong><br />

parallelismo: descrive infatti una pipeline a quattro sta<strong>di</strong> (caricamento<br />

istruzione, caricamento dati, esecuzione, salvataggio risultati).<br />

Il concetto <strong>di</strong> pipeline viene poi sviluppato dal ricercatore Robert Tomasulo<br />

dell’IBM intorno agli anni ‘60. Il primo sistema dotato <strong>di</strong> pipeline fu infatti il<br />

supercomputer IBM System 360/91 presentato nel 1966 che grazie al<strong>la</strong> pipeline


52 Capitolo 3<br />

otteneva un incremento anche del 33%. La pipeline si <strong>di</strong>ffuse rapidamente nei<br />

supercomputer e nei server. Il primo microprocessore a utilizzare una pipeline<br />

fu il MOS Technology 6502 che tramite una semplice pipeline forniva<br />

prestazioni superiori a quelli del<strong>la</strong> concorrenza a una frazione del loro costo.<br />

Nel settore <strong>di</strong> micro<strong>processori</strong> le pipeline <strong>di</strong>vennero comuni con i <strong>processori</strong><br />

RISC, <strong>la</strong> cui semplicità consentì <strong>di</strong> utilizzare un’architettura a pipeline completa<br />

fin dalle loro prime implementazioni negli anni ottanta. I progetti Berkeley<br />

RISC e MIPS infatti, avevano già una pipeline. I <strong>processori</strong> CISC utilizzarono<br />

un’architettura a pipeline completa so<strong>la</strong>mente al<strong>la</strong> fine degli anni 80 per via<br />

delle maggiori <strong>di</strong>fficoltà <strong>di</strong> implementazione.<br />

Punti Deboli<br />

L’implementazione <strong>di</strong> una pipeline non sempre moltiplica il throughput.<br />

I problemi principali <strong>di</strong> gestione del<strong>la</strong> pipeline sono due: il problema legato al<strong>la</strong><br />

presenza <strong>di</strong> istruzioni che possono richiedere l’e<strong>la</strong>borazione <strong>di</strong> dati non ancora<br />

<strong>di</strong>sponibili e il problema legato al<strong>la</strong> presenza <strong>di</strong> salti con<strong>di</strong>zionati.<br />

Il primo problema deriva dal <strong>la</strong>voro parallelo delle unità.<br />

Supponiamo che <strong>la</strong> CPU con pipeline debba eseguire il seguente frammento <strong>di</strong><br />

co<strong>di</strong>ce:<br />

Istruzione 1:<br />

Istruzione 2:<br />

c = a + b<br />

d = c −1<br />

La prima istruzione deve prelevare i numeri contenuti nelle variabili “a” e “b”,<br />

sommarli e porli nel<strong>la</strong> variabile “c”. La seconda istruzione deve prelevare il<br />

valore contenuto nel<strong>la</strong> variabile “c”, sottrarlo <strong>di</strong> uno e salvare il risultato in “d”.


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 53<br />

Ma <strong>la</strong> seconda istruzione non potrà essere e<strong>la</strong>borata (EX) fino a quando il dato<br />

del<strong>la</strong> prima operazione non sarà <strong>di</strong>sponibile in memoria (MEM) e quin<strong>di</strong> <strong>la</strong><br />

seconda operazione dovrà bloccarsi per attendere il completamento del<strong>la</strong> prima<br />

e quin<strong>di</strong> questo ridurrà il throughput complessivo.<br />

Figura 3.6- La necessità <strong>di</strong> aspettare il dato <strong>di</strong>sponibile genera una “bol<strong>la</strong>” nel<strong>la</strong><br />

pipeline che comporta una riduzione del throughput.<br />

Questo tipo <strong>di</strong> problematiche è noto con il nome <strong>di</strong> “Alea sui dati”<br />

Il secondo problema consiste nei salti con<strong>di</strong>zionati. Nell’esecuzione <strong>dei</strong><br />

programmi si possono incontrare istruzioni con<strong>di</strong>zionate che impongono, a<br />

fronte del verificarsi <strong>di</strong> una specifica con<strong>di</strong>zione, l’interruzione del flusso<br />

abituale del programma e mandare in esecuzione un altro pezzo <strong>di</strong> programma<br />

in<strong>di</strong>cato dall’istruzione <strong>di</strong> salto. Ogni volta che questo accade il<br />

microprocessore si trova a dover eseguire un nuovo flusso <strong>di</strong> operazioni e<br />

quin<strong>di</strong> deve svuotare <strong>la</strong> pipeline del precedente flusso e caricare il nuovo flusso.<br />

Ovviamente queste operazioni fanno sprecare cicli <strong>di</strong> clock e quin<strong>di</strong> fanno<br />

crol<strong>la</strong>re il throughput. Per ridurre questo problema (noto come Alea <strong>di</strong><br />

controllo) le CPU adottano delle unità funzionali chiamate unità <strong>di</strong> pre<strong>di</strong>zione<br />

<strong>dei</strong> salti (in inglese Branch Pre<strong>di</strong>ction Unit) che fanno delle previsioni sul flusso<br />

del programma. Queste unità riducono notevolmente i cicli persi per i salti.<br />

Evoluzioni


54 Capitolo 3<br />

Gli stu<strong>di</strong> per migliorare le prestazioni delle CPU hanno portato ad affermare <strong>la</strong><br />

strategia <strong>di</strong> integrare in un unico microprocessore più pipeline che funzionano<br />

in parallelo. Questi micro<strong>processori</strong> sono definiti supersca<strong>la</strong>ri, in quanto sono in<br />

grado <strong>di</strong> eseguire me<strong>di</strong>amente più <strong>di</strong> un’operazione per ciclo <strong>di</strong> clock. Queste<br />

pipeline ovviamente rendono ancora più complessa <strong>la</strong> gestione <strong>dei</strong> problemi <strong>di</strong><br />

coerenza <strong>dei</strong> dati e <strong>dei</strong> salti con<strong>di</strong>zionati.<br />

Nelle CPU moderne inoltre, le pipeline non sono composte da soli cinque sta<strong>di</strong><br />

ma in realtà ne utilizzano molti <strong>di</strong> più (anche fino a 30). Questo si è reso<br />

necessario per potere innalzare <strong>la</strong> frequenza <strong>di</strong> clock. Spezzettando le singole<br />

operazioni necessarie per completare un’istruzione in tante sotto operazioni si<br />

può elevare <strong>la</strong> frequenza del<strong>la</strong> CPU dato che ogni unità deve svolgere<br />

un’operazione più semplice e quin<strong>di</strong> può impiegare meno tempo per completare<br />

<strong>la</strong> sua operazione. Questa scelta <strong>di</strong> progettazione consente effettivamente <strong>di</strong><br />

aumentare <strong>la</strong> frequenza <strong>di</strong> funzionamento delle CPU ma rende critico il<br />

problema <strong>dei</strong> salti con<strong>di</strong>zionati. In caso <strong>di</strong> un salto con<strong>di</strong>zionato non previsto il<br />

processore può essere costretto a svuotare e ricaricare una pipeline <strong>di</strong> numerosi<br />

sta<strong>di</strong>.<br />

Come esempio <strong>di</strong> pipeline profonda ricor<strong>di</strong>amo quel<strong>la</strong> del Pentium ® 4 a 20 sta<strong>di</strong>.<br />

Figura 3.7- La pipeline del Pentium ® 4 costituita da 20 sta<strong>di</strong>


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 55<br />

Front End e Back End<br />

Concettualmente ogni processore può essere sud<strong>di</strong>viso in due blocchi principali.<br />

Il primo si occupa <strong>di</strong> prelevare le istruzioni dal<strong>la</strong> gerarchia <strong>di</strong> memoria e <strong>di</strong><br />

pre<strong>di</strong>sporle al<strong>la</strong> esecuzione. Questo significa che le istruzioni devono essere<br />

deco<strong>di</strong>ficate (me<strong>di</strong>ante sud<strong>di</strong>visione in microistruzioni o deco<strong>di</strong>fica hardware)<br />

per renderle "comprensibili" dalle unità <strong>di</strong> esecuzione e quin<strong>di</strong> <strong>di</strong>stribuite<br />

ognuna al<strong>la</strong> propria unità <strong>di</strong> esecuzione. Questo blocco è conosciuto come il<br />

Front End del processore. Naturalmente quante più istruzioni esso riesce a<br />

inviare alle unità <strong>di</strong> esecuzione tanto più è efficiente. Importante per questo<br />

sta<strong>di</strong>o è <strong>la</strong> comunicazione con <strong>la</strong> gerarchia <strong>di</strong> memoria (quin<strong>di</strong> le modalità e <strong>la</strong><br />

velocità con cui essa opera) per rifornire continuamente <strong>di</strong> istruzioni il Front<br />

End, e <strong>la</strong> pre<strong>di</strong>zione delle <strong>di</strong>ramazioni che cerca <strong>di</strong> impe<strong>di</strong>re che <strong>la</strong> pipeline del<br />

processore abbia sta<strong>di</strong> che non eseguono alcuna operazione in attesa che sia<br />

noto l’esito del<strong>la</strong> con<strong>di</strong>zione <strong>di</strong> <strong>di</strong>ramazione.<br />

Il secondo sta<strong>di</strong>o del processore è quello che esegue effettivamente il "<strong>la</strong>voro"<br />

cioè esegue le istruzioni e fornisce i risultati. Questo sta<strong>di</strong>o è chiamato Back<br />

End. L’efficienza <strong>di</strong> questo sta<strong>di</strong>o è fortemente con<strong>di</strong>zionata dal numero <strong>di</strong><br />

unità <strong>di</strong> esecuzione <strong>di</strong> cui <strong>di</strong>spone (per cominciare l’esecuzione <strong>di</strong> più <strong>di</strong> una<br />

istruzione per ciclo) e dal tempo <strong>di</strong> cui necessita ciascuna unità per processare<br />

una istruzione. I <strong>processori</strong> moderni fanno uso dell’esecuzione fuori or<strong>di</strong>ne<br />

proprio per fare fronte al<strong>la</strong> carenza <strong>di</strong> risorse (registri, unità <strong>di</strong> esecuzione) <strong>di</strong><br />

cui generalmente soffrono.


56 Capitolo 3<br />

Quello che qui si intende rimarcare è che questi due sta<strong>di</strong> influenzano<br />

reciprocamente le proprie prestazioni. Un Back End che esegue un elevato<br />

numero <strong>di</strong> istruzioni per clock deve essere continuamente rifornito <strong>di</strong> nuove<br />

istruzioni dal Front End da e<strong>la</strong>borare per non essere sottoutilizzato.<br />

Analogamente per facilitare il <strong>la</strong>voro <strong>di</strong> <strong>di</strong>stribuzione delle istruzioni alle unità<br />

<strong>di</strong> esecuzione del Front End le istruzioni devono essere eseguite efficacemente<br />

per liberare le risorse che questi deve alimentare e <strong>di</strong>rimere le <strong>di</strong>ramazioni.<br />

Multiple issue (<strong>processori</strong> supersca<strong>la</strong>ri)<br />

La seconda strategia <strong>di</strong> ILP <strong>di</strong>namico prevede l’utilizzo <strong>di</strong> più unità <strong>di</strong><br />

esecuzione in<strong>di</strong>pendenti che eseguano istruzioni in parallelo. Questa tecnica<br />

viene detta multiple issue e il suo svantaggio principale è una maggior<br />

complessità del processore. <strong>Oltre</strong> al<strong>la</strong> presenza <strong>di</strong> più unità <strong>di</strong> calcolo, il<br />

processore deve <strong>di</strong>sporre <strong>di</strong> un bus interno ampio, capace <strong>di</strong> trasportare i dati tra<br />

le varie unità senza colli <strong>di</strong> bottiglia. Inoltre le singole unità funzionali come le<br />

cache devono poter ri<strong>la</strong>sciare più dati in parallelo e gli stessi registri devono<br />

poter <strong>legge</strong>re e scrivere più dati in parallelo.<br />

Le architetture in grado <strong>di</strong> eseguire più istruzioni in parallelo sono dette<br />

supersca<strong>la</strong>ri, e l’analisi del parallelismo a livello <strong>di</strong> istruzione per questa<br />

tipologia <strong>di</strong> <strong>processori</strong> è ovviamente fondamentale.<br />

Cenni storici<br />

Le architetture supersca<strong>la</strong>ri ebbero origine nell’ambiente RISC, dato che questo<br />

tipo <strong>di</strong> design richiede unità funzionali semplici, che possono essere incluse in


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 57<br />

più esemp<strong>la</strong>ri in una unica CPU. Questa è <strong>la</strong> ragione per cui questi <strong>processori</strong><br />

erano più veloci <strong>dei</strong> CISC tra gli anni ‘80 e gli anni ‘90. Tuttavia, col progresso<br />

del<strong>la</strong> tecnologia, anche design ingombranti come l’IA-32 poterono essere<br />

progettati in modo supersca<strong>la</strong>re.<br />

Punti Deboli<br />

Osserviamo innanzitutto che il numero e <strong>la</strong> tipologia <strong>di</strong> unità funzionali possono<br />

limitare il numero <strong>di</strong> esecuzioni contemporanee: banalmente se il processore è<br />

dotato <strong>di</strong> quattro unità <strong>di</strong> calcolo, questo non potrà eseguire più <strong>di</strong> quattro<br />

istruzioni in parallelo anche se nel co<strong>di</strong>ce fossero presenti più istruzioni<br />

eseguibili in parallelo.<br />

Le unità <strong>di</strong> controllo, ovvero quelle che stabiliscono quali istruzioni possono<br />

essere eseguite in parallelo e le inviano alle rispettive unità, <strong>di</strong>ventano critiche<br />

in queste architetture. Il loro compito infatti non è semplice, dato che<br />

un’istruzione può richiedere il risultato del<strong>la</strong> precedente come proprio<br />

operando, oppure può dover impiegare il dato conservato in un registro usato<br />

anche dall’altra istruzione; il risultato può quin<strong>di</strong> cambiare secondo l’or<strong>di</strong>ne<br />

d’esecuzione delle istruzioni. La maggior parte delle CPU moderne de<strong>di</strong>ca un<br />

elevato numero <strong>di</strong> transistor allo svolgimento <strong>di</strong> questo compito, per permettere<br />

al processore <strong>di</strong> funzionare a pieno regime in modo costante; compito che si è<br />

reso sempre più importante con l’aumento del numero delle unità. Mentre le<br />

prime CPU supersca<strong>la</strong>ri possedevano due ALU ed una FPU, processore del<br />

2003 come ad esempio il PowerPC 970 possedeva già quattro ALU, due FPU e


58 Capitolo 3<br />

due unità SIMD. Se l’unità <strong>di</strong> deco<strong>di</strong>fica delle istruzioni non mantiene occupate<br />

tutte le unità funzionali del processore, le prestazioni ne soffrono grandemente.<br />

Evoluzioni<br />

Attualmente è impensabile un futuro miglioramento sensibile del sistema <strong>di</strong><br />

controllo, ponendo <strong>di</strong> fatto un limite ai miglioramenti prestazionali <strong>dei</strong><br />

<strong>processori</strong> supersca<strong>la</strong>ri. Il progetto VLIW (Very Long Instruction Word) cerca<br />

una soluzione scaricando parte del processo <strong>di</strong> controllo delle istruzioni in fase<br />

<strong>di</strong> scrittura del programma e <strong>di</strong> compi<strong>la</strong>zione, evitando al processore <strong>di</strong> doverlo<br />

ripetere ad ogni esecuzione del programma.<br />

Un’altra evoluzione <strong>dei</strong> <strong>processori</strong> supersca<strong>la</strong>ri è l’integrazione <strong>di</strong> più<br />

<strong>processori</strong> in<strong>di</strong>pendenti (core) in un singolo processore, come presenteremo nel<br />

paragrafo (3.2.3). Un approccio interme<strong>di</strong>o prevede una separazione logica e<br />

non fisica delle pipeline con le pipeline separate ma i circuiti <strong>di</strong> controllo e<br />

gestione ancora in comune. Si par<strong>la</strong> in questo caso si Multi Thread e verrà<br />

illustrata nel paragrafo (3.2.2).<br />

La realizzazione <strong>di</strong> <strong>processori</strong> multi core e multi threa<strong>di</strong>ng sono una soluzione<br />

migliore rispetto al<strong>la</strong> semplice aggiunta <strong>di</strong> nuove unità pipeline dato che ogni<br />

nuova pipeline aumenta <strong>la</strong> possibilità <strong>di</strong> eseguire istruzioni che siano in conflitto<br />

con altre e quin<strong>di</strong> spingersi oltre quattro pipeline risulta spesso sconveniente.<br />

Eseguendo più thread in parallelo si eliminano i problemi dati che i thread sono<br />

separati e quin<strong>di</strong> le varie pipeline non possono entrare in conflitto tra <strong>di</strong> loro.<br />

Questi <strong>processori</strong> però costringono i programmatori a realizzare programmi<br />

paralleli per fruttare al meglio i <strong>processori</strong> moderni e <strong>la</strong> realizzazione <strong>di</strong>


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 59<br />

programmi paralleli non è semplice ed per alcuni algoritmi non esistono<br />

nemmeno meto<strong>di</strong> per renderli paralleli in modo efficiente.<br />

Esecuzione fuori or<strong>di</strong>ne<br />

Tutti i <strong>processori</strong> moderni utilizzano le pipeline, le quali, quando si trovano in<br />

presenza <strong>di</strong> alee sui dati o sul flusso <strong>di</strong> controllo, devono introdurre degli stalli<br />

(detti anche bolle) per permettere <strong>la</strong> risoluzione delle alee stesse.<br />

Il parallelismo delle istruzioni migliora pertanto se vengono ridotte le Alee. Una<br />

tecnica per ridurle consiste nel riorganizzare le istruzioni opportunamente.<br />

Consideriamo ad esempio il seguente co<strong>di</strong>ce:<br />

Istruzione 1:<br />

Istruzione 2:<br />

Istruzione 3:<br />

h = a + b<br />

f = h + d<br />

g = w * 100<br />

La seconda istruzione <strong>di</strong>pende dal risultato del<strong>la</strong> prima istruzione mentre <strong>la</strong><br />

terza istruzione è in<strong>di</strong>pendente dalle altre. Eseguendo le istruzioni all’interno <strong>di</strong><br />

una pipeline a 5 sta<strong>di</strong> si avrebbe uno stallo (o due, a seconda <strong>di</strong> come viene<br />

implementata <strong>la</strong> pipeline) tra <strong>la</strong> prima e <strong>la</strong> seconda istruzione. Riorganizzando<br />

le istruzioni ed inviando al<strong>la</strong> pipeline <strong>la</strong> prima istruzione, poi <strong>la</strong> terza istruzione<br />

(in<strong>di</strong>pendente dalle altre) e infine <strong>la</strong> seconda istruzione, si ottiene un’esecuzione<br />

senza stalli. Questa modalità <strong>di</strong> esecuzione viene detta out-of-order, dato che le<br />

istruzioni vengono eseguite e completate fuori or<strong>di</strong>ne rispetto al co<strong>di</strong>ce<br />

sviluppato dal programmatore.


60 Capitolo 3<br />

Figura 3.8 - Schema concettuale dell’esecuzione fuori or<strong>di</strong>ne. Il programma viene<br />

caricato come istruzioni seriali, le istruzioni vengono analizzate, rior<strong>di</strong>nate tenendo<br />

conto delle <strong>di</strong>pendenze, eseguite in parallelo, ed rior<strong>di</strong>nate prima <strong>di</strong> provvedere al<br />

salvataggio <strong>dei</strong> dati in memoria.<br />

È ovvio che l’esecuzione fuori or<strong>di</strong>ne è <strong>di</strong> per se stessa causa <strong>di</strong> abbandono<br />

del<strong>la</strong> logica sequenziale del programma che invece deve essere preservata.<br />

Occorre perciò un meccanismo <strong>di</strong> emissione/completamento capace <strong>di</strong> garantire<br />

che il risultato dell’esecuzione fuori or<strong>di</strong>ne sia equivalente all’esecuzione<br />

strettamente sequenziale.<br />

Nel seguito vengono presentati i due principali meto<strong>di</strong> per <strong>la</strong> gestione<br />

dell’esecuzione fuori or<strong>di</strong>ne:<br />

• Metodo del Reorder Buffer. Le istruzioni possono essere emesse in<br />

or<strong>di</strong>ne o fuori or<strong>di</strong>ne e possono completare fuori or<strong>di</strong>ne, ma sono<br />

forzate a mo<strong>di</strong>ficare lo stato del<strong>la</strong> macchina in or<strong>di</strong>ne. La tecnica si basa<br />

sull’interposizione <strong>di</strong> un buffer tra l’unità <strong>di</strong> emissione e quel<strong>la</strong> <strong>di</strong>


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 61<br />

scrittura nei registri (o in memoria): le istruzioni completate vengono<br />

ritirate dal buffer secondo l’or<strong>di</strong>ne del programma.<br />

• Metodo dell’History Buffer. Le istruzioni possono essere emesse in<br />

or<strong>di</strong>ne o fuori or<strong>di</strong>ne e possono completare e aggiornare lo stato <strong>di</strong><br />

macchina in qualsiasi or<strong>di</strong>ne, tuttavia viene conservata l’informazione<br />

necessaria a ripristinare lo stato coerente in presenza <strong>di</strong> situazioni <strong>di</strong><br />

conflitto (salti e interruzioni).<br />

Metodo del Reorder Buffer<br />

Il metodo del Reorder Buffer (ROB), utilizzato in numerosi <strong>processori</strong> moderni,<br />

permette alle istruzioni <strong>di</strong> essere eseguite fuori or<strong>di</strong>ne, ma imponendo <strong>la</strong><br />

scrittura <strong>dei</strong> risultati in modo coerente rispetto al modello sequenziale. Il ROB è<br />

un buffer interposto tra le unità funzionali e i registri, come mostrato in Figura<br />

3.9.<br />

Figura 3.9 - Organizzazione <strong>di</strong> una pipeline col metodo del Reordering Buffer


62 Capitolo 3<br />

Lo schema <strong>di</strong> Figura 3.9 presuppone che i risultati prodotti dall’esecuzione delle<br />

istruzioni vengano depositati nel ROB e da qui trasferiti ai registri. Più<br />

specificatamente il ROB ha queste funzioni:<br />

• tenere traccia dell’or<strong>di</strong>ne naturale delle istruzioni. A tal fine, quando<br />

un’istruzione viene emessa (in or<strong>di</strong>ne) viene anche presa per essa,<br />

sequenzialmente, una posizione nel ROB;<br />

• servire da appoggio per i risultati delle istruzioni completate<br />

(eventualmente fuori or<strong>di</strong>ne);<br />

• tenere traccia del completamento delle istruzioni, in modo da<br />

permettere l’estrazione (ritiro) in or<strong>di</strong>ne <strong>dei</strong> risultati delle istruzioni<br />

completate.<br />

Con lo schema <strong>di</strong> Figura 3.9, le istruzioni sono avviate alle unità funzionali solo<br />

se esse non <strong>di</strong>pendono dai risultati delle istruzioni che ancora non sono uscite<br />

dal ROB. Quando una istruzione viene avviata verso un’unità funzionale viene<br />

presa per essa una posizione in ROB, secondo l’or<strong>di</strong>ne testuale del programma.<br />

Quando un’istruzione termina, il risultato da esso prodotto viene scritto nel<br />

ROB. I risultati vengono estratti dal ROB (e scritti nei registri <strong>di</strong> destinazione)<br />

prelevandoli dal<strong>la</strong> testa del ROB, in modo da mantenere l’or<strong>di</strong>ne del<br />

programma, garantendo così <strong>la</strong> coerenza tra lo stato macchina e il modello<br />

sequenziale <strong>di</strong> esecuzione.<br />

Il ROB è gestito come una coda circo<strong>la</strong>re. A tale scopo sono richiesti due<br />

puntatori: un puntatore <strong>di</strong> testa Pt e un puntatore <strong>di</strong> coda Pc. Sono considerate<br />

valide le entrate che si trovano nelle posizioni comprese tra quel<strong>la</strong> puntata da Pt


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 63<br />

e quel<strong>la</strong> puntata da Pc. Un elemento <strong>di</strong> ROB è costituito dalle 4 componenti {C,<br />

PC, Rd, RIS}, dove:<br />

C: bit <strong>di</strong> completamento; <strong>di</strong>ce se l’istruzione ha completato <strong>la</strong><br />

fase <strong>di</strong> esecuzione;<br />

PC: valore del program counter dell’istruzione;<br />

Rd: identificatore (tag) del registro <strong>di</strong> destinazione;<br />

RIS: risultato prodotto dall’istruzione<br />

L’utilizzo del ROB, pur permettendo alle istruzioni <strong>di</strong> terminare <strong>la</strong> loro<br />

esecuzione fuori or<strong>di</strong>ne, forza lo stato del processore ad essere aggiornato<br />

nell’or<strong>di</strong>ne del programma. Di conseguenza, un’istruzione che prevede <strong>la</strong> lettura<br />

<strong>di</strong> dati ancora in ROB, cioè non ancora scritti nei rispettivi registri <strong>di</strong><br />

destinazione, deve essere tenuta in stallo nel registro <strong>di</strong> emissione, bloccando<br />

anche le istruzioni che <strong>la</strong> seguono. Ciò porta inevitabilmente al<strong>la</strong> riduzione delle<br />

prestazioni.<br />

Un metodo per ridurre questa penalizzazione consiste nel <strong>di</strong>sporre <strong>di</strong> percorsi <strong>di</strong><br />

bypass che connettono gli elementi presenti all’interno del ROB con le uscite<br />

del banco <strong>dei</strong> registri (Figura 3.10). In questo modo le istruzioni possono usare,<br />

come operan<strong>di</strong> sia i dati contenuti nel banco <strong>dei</strong> registri, sia quelli che ancora si<br />

trovano nel ROB, evitando l’attesa nel registro <strong>di</strong> emissione per <strong>la</strong> scrittura nel<br />

banco <strong>dei</strong> registri. La presenza <strong>dei</strong> percorsi <strong>di</strong> bypass non impe<strong>di</strong>sce che lo stato<br />

del<strong>la</strong> macchina sia coerente, dal momento che il banco <strong>dei</strong> registri, esattamente<br />

come avviene in assenza <strong>dei</strong> percorsi <strong>di</strong> bypass, viene aggiornato in modo<br />

coerente col modello sequenziale <strong>di</strong> esecuzione del programma.


64 Capitolo 3<br />

Figura 3.10- Percorsi <strong>di</strong> by-pass e ROB. Essi rendendo imme<strong>di</strong>atamente <strong>di</strong>sponibili i<br />

dati appena calco<strong>la</strong>ti alle istruzioni in attesa <strong>di</strong> emissione, riducono al minimo il tempo<br />

<strong>di</strong> permanenza delle istruzioni nel registro <strong>di</strong> emissione.<br />

Una soluzione <strong>di</strong>fferente è quel<strong>la</strong> <strong>di</strong> introdurre in ingresso alle unità funzionali<br />

<strong>dei</strong> propri buffer 4<br />

; questi consentono <strong>di</strong> parcheggiare eventuali istruzioni che<br />

richiedono <strong>di</strong> <strong>legge</strong>re dati ancora non scritti, evitando lo stallo nel registro <strong>di</strong><br />

emissione.<br />

Metodo dell’History Buffer<br />

La gestione dell’esecuzione fuori or<strong>di</strong>ne me<strong>di</strong>ante l’uso <strong>di</strong> un History Buffer<br />

(HB), ossia <strong>di</strong> un registro che tenga traccia dell’evoluzione dello stato del<strong>la</strong><br />

macchina durante l’esecuzione <strong>di</strong> un programma, nasce dall’esigenza <strong>di</strong><br />

migliorare le prestazioni del ROB.<br />

L’idea al<strong>la</strong> base del metodo è quel<strong>la</strong> <strong>di</strong> permettere alle istruzioni <strong>di</strong> completare<br />

l’esecuzione, permettendo <strong>la</strong> scrittura <strong>dei</strong> registri ma conservando abbastanza<br />

informazioni sugli stati passati da poter ripristinare, in caso <strong>di</strong> necessità, lo stato<br />

4 Questi registri sono chiamati “reservation stations”


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 65<br />

appropriato. L’ History Buffer è un registro organizzato in modo assai simile al<br />

ROB e inserito nell’ architettura come mostrato in Figura 3.11.<br />

Figura 3.11- Organizzazione del<strong>la</strong> pipeline con un History Buffer (HB) Esso entra in<br />

gioco in caso <strong>di</strong> necessità, rimettendo i vecchi valori nei registri mo<strong>di</strong>ficati<br />

specu<strong>la</strong>tivamente. [8].<br />

Quando un’istruzione viene inviata dall’unità <strong>di</strong> emissione a un’unità<br />

funzionale, viene inserito un nuovo elemento in HB. HB è gestito come una<br />

coda circo<strong>la</strong>re, in modo analogo al ROB.<br />

Un elemento <strong>di</strong> HB è costituito da 4 componenti: {C, PC, Rd, OLD}, dove C,<br />

PC e Rd hanno lo stesso significato del caso del ROB, mentre <strong>la</strong> componente<br />

OLD viene usata per tenere il valore contenuto in Rd al momento<br />

dell’emissione dell’istruzione. In caso <strong>di</strong> necessità, questo valore viene riscritto<br />

nel registro in modo da ripristinare una situazione <strong>di</strong> stato coerente.<br />

Quando un’istruzione arriva in testa a HB col bit <strong>di</strong> completamento a l (ovvero<br />

l’istruzione è stata eseguita) e non è sorta nessuna necessità <strong>di</strong> ripristinare lo<br />

stato coerente, il corrispondente elemento in HB non è più necessario e viene<br />

eliminato (aggiornando il Pt).


66 Capitolo 3<br />

Poiché l’or<strong>di</strong>ne <strong>di</strong> emissione garantisce <strong>la</strong> coerenza rispetto alle <strong>di</strong>pendenze <strong>dei</strong><br />

dati, i motivi per i quali si deve ripristinare lo stato corrente sono legati alle<br />

previsioni <strong>di</strong> salto errate e alle interruzioni.<br />

In presenza <strong>di</strong> interruzione, l’emissione <strong>di</strong> nuove istruzioni da parte dell’Issue<br />

Register viene imme<strong>di</strong>atamente bloccata. Sul<strong>la</strong> base del criterio <strong>di</strong> risoluzione<br />

dell’interruzione, viene identificata l’istruzione in pipeline che <strong>di</strong>scrimina quelle<br />

che vengono portate a completamento da quelle che vengono. Le istruzioni che<br />

devono completare scrivono su RF e vengono estratte da HB. Per le istruzioni<br />

che seguono l’ultima da portare a termine, che fossero eventualmente<br />

completate e avessero scritto il loro registro <strong>di</strong> destinazione, viene ripristinato il<br />

vecchio valore prendendoli da HB. Servita l’interruzione, il programma riparte<br />

dal<strong>la</strong> prima istruzione che non è stata fatta procedere.<br />

Pre<strong>di</strong>zione <strong>dei</strong> salti<br />

Per ridurre al minimo l’impatto delle alee <strong>di</strong> controllo, i micro<strong>processori</strong><br />

includono quasi sempre una qualche tipologia <strong>di</strong> unità <strong>di</strong> pre<strong>di</strong>zione delle<br />

<strong>di</strong>ramazioni. Questa unità, tenendo traccia <strong>dei</strong> risultati delle istruzioni <strong>di</strong> salto<br />

eseguiti, ogni volta in cui si incontrano delle istruzioni <strong>di</strong> salto cerca <strong>di</strong><br />

prevedere se il salto verrà eseguito o no. La pre<strong>di</strong>zione <strong>dei</strong> salti permette <strong>di</strong><br />

caricare in anticipo le istruzioni successive al salto e, nel caso <strong>di</strong> corretta<br />

pre<strong>di</strong>zione del salto, il processore non deve bloccare o svuotare <strong>la</strong> pipeline.<br />

Esistono molte tecniche per implementare <strong>la</strong> pre<strong>di</strong>zione <strong>dei</strong> saltati. Tecniche più<br />

complesse portano ad ottenere percentuali <strong>di</strong> previsione migliori ma<br />

comportano anche costi maggiori per via del maggior numero <strong>di</strong> transistor


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 67<br />

impiegato e quin<strong>di</strong> spesso non viene utilizzata <strong>la</strong> migliore strategia <strong>di</strong> previsione<br />

ma strategie più semplici e quin<strong>di</strong> più economiche da implementare.<br />

Pre<strong>di</strong>zione elementare<br />

I primi esemp<strong>la</strong>ri <strong>di</strong> SPARC e MIPS (due delle prime architetture RISC<br />

commerciali) facevano una specie <strong>di</strong> pre<strong>di</strong>zione, molto elementare:<br />

consideravano sempre il salto come “non accettato”, e deco<strong>di</strong>ficavano<br />

l’istruzione seguente. L’operazione <strong>di</strong> salto veniva effettutata solo dopo che <strong>la</strong><br />

con<strong>di</strong>zione veniva valutata.<br />

Entrambe le CPU effettuavano questa "pre<strong>di</strong>zione" in fase <strong>di</strong> deco<strong>di</strong>fica e<br />

de<strong>di</strong>cavano al fetch delle istruzioni un solo ciclo <strong>di</strong> clock. In questo modo per<br />

effettuare un salto servivano due cicli <strong>di</strong> clock, ma dopo il primo <strong>la</strong> CPU aveva<br />

già effettuato il fetch dell’istruzione subito successiva al salto; piuttosto che<br />

sprecare questo <strong>la</strong>voro, entrambi i micro<strong>processori</strong> eseguivano anche queste<br />

istruzioni, avvantaggiandosi magari per fasi successive del <strong>la</strong>voro.<br />

Pre<strong>di</strong>zione statica<br />

I <strong>processori</strong> che impiegano questa tecnica considerano sempre i salti verso <strong>la</strong><br />

parte precedente del co<strong>di</strong>ce come “accettati” (ipotizzando che siano le istruzioni<br />

riguardanti un ciclo) e i salti in avanti sempre come “non accettati” (ipotizzando<br />

che siano uscite precoci dal ciclo o altre funzioni <strong>di</strong> programmazione<br />

partico<strong>la</strong>ri). Per cicli che si ripetono molte volte, questa tecnica fallisce solo al<strong>la</strong><br />

fine del ciclo.


68 Capitolo 3<br />

La pre<strong>di</strong>zione statica è usata come “paracadute” quando non ci sono elementi<br />

per usare altre tecniche come <strong>la</strong> pre<strong>di</strong>zione <strong>di</strong>namica e il processore deve andare<br />

“al<strong>la</strong> cieca”.<br />

Pre<strong>di</strong>zione del<strong>la</strong> linea successiva<br />

Alcuni <strong>processori</strong> supersca<strong>la</strong>ri (es.: MIPS R8000 e DEC Alpha EV6/EV8)<br />

eseguivano il fetch <strong>di</strong> una linea <strong>di</strong> istruzioni, anche il puntatore al<strong>la</strong> linea<br />

successiva. Questo metodo è piuttosto <strong>di</strong>verso dagli altri trattati, perché esegue<br />

sia <strong>la</strong> previsione del salto, che <strong>la</strong> previsione del<strong>la</strong> <strong>di</strong>rezione del salto stesso.<br />

Quando un puntatore in<strong>di</strong>ca un gruppo <strong>di</strong> 2, 4 o 8 istruzioni, solitamente<br />

l’istruzione ricercata non è <strong>la</strong> prima (per un fatto statistico), così <strong>la</strong> scansione<br />

delle prime istruzioni è tempo perso. Generalizzando, vengono scartate<br />

rispettivamente 0,5, 1,5 e 3,5 istruzioni deco<strong>di</strong>ficate. Lo stesso <strong>di</strong>scorso vale per<br />

le istruzioni successive all’istruzione <strong>di</strong> salto, che devono essere scartate con<br />

identica <strong>di</strong>stribuzione me<strong>di</strong>a.<br />

Le istruzioni scartate dall’unità <strong>di</strong> pre<strong>di</strong>zione fanno guadagnare quasi un<br />

completo ciclo <strong>di</strong> fetch, anche con pre<strong>di</strong>zioni eseguite solo sul<strong>la</strong> linea<br />

successiva e in un solo ciclo <strong>di</strong> clock.<br />

Un esempio <strong>di</strong> processore che utilizza <strong>la</strong> pre<strong>di</strong>zione del<strong>la</strong> linea successiva è il<br />

Pentium ® 4.<br />

Pre<strong>di</strong>zione <strong>di</strong>namica<br />

Una possibilità consiste nel verificare l’in<strong>di</strong>rizzo dell’istruzione per control<strong>la</strong>re<br />

se l’ultima volta che si era considerata quell’istruzione il salto fosse stato<br />

eseguito: in caso positivo, si caricano le istruzioni successive a partire dal<strong>la</strong>


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 69<br />

stessa posizione del<strong>la</strong> volta precedente. Questa tecnica viene chiamata<br />

pre<strong>di</strong>zione <strong>di</strong>namica <strong>dei</strong> salti.<br />

Un modo per implementare questa strategia consiste nell’utilizzare un buffer <strong>di</strong><br />

pre<strong>di</strong>zione <strong>dei</strong> salti (branch pre<strong>di</strong>ction buffer), o tabel<strong>la</strong> <strong>di</strong> storia <strong>dei</strong> salti<br />

(branch history table) . Un buffer <strong>di</strong> previsione <strong>dei</strong> salti è una picco<strong>la</strong> memoria<br />

in<strong>di</strong>cizzata attraverso <strong>la</strong> parte bassa dell’in<strong>di</strong>rizzo dell’istruzione <strong>di</strong> salto. La<br />

memoria contiene un bit che in<strong>di</strong>ca se recentemente il salto è stato eseguito o<br />

meno.<br />

Questo semplice schema a un bit ha <strong>dei</strong> problemi <strong>di</strong> prestazioni: anche se un<br />

salto è quasi sempre preso, lo pre<strong>di</strong>remo probabilmente due volte in maniera<br />

scorretta, piuttosto che una volta, quando è effettivamente non preso.<br />

Si consideri, ad esempio, un salto con<strong>di</strong>zionato presente all’interno <strong>di</strong> un ciclo,<br />

e si supponga che il salto venga eseguito nove volte <strong>di</strong> seguito, e poi non venga<br />

eseguito per una volta. A regime <strong>la</strong> previsione non sarà corretta nel<strong>la</strong> prima e<br />

nell’ultima iterazione del ciclo. L’errore sull’ultima iterazione è inevitabile in<br />

quanto <strong>la</strong> previsione <strong>di</strong>rà che il salto deve essere eseguito, essendo stato<br />

eseguito nove volte <strong>di</strong> seguito fino a quel punto. L’errore sul<strong>la</strong> prima iterazione<br />

si verifica perché il bit è stato complementato in occasione dell’esecuzione<br />

dell’ultima iterazione del ciclo, quando il salto non era stato eseguito. Di<br />

conseguenza l’accuratezza del<strong>la</strong> previsione per questo salto (che viene eseguito<br />

nel 90% <strong>dei</strong> casi) è pari all’8O% (due previsioni sbagliate e otto corrette).


70 Capitolo 3<br />

Pre<strong>di</strong>zione bimodale<br />

Questa tecnica è una evoluzione del<strong>la</strong> precedente e migliora i salti altamente<br />

rego<strong>la</strong>ri. In linea <strong>di</strong> principio si vorrebbe che per questi salti l’accuratezza del<strong>la</strong><br />

pre<strong>di</strong>zione corrispondesse al<strong>la</strong> frequenza <strong>di</strong> esecuzione del salto. Per rime<strong>di</strong>are a<br />

questa mancanza si usano spesso degli schemi <strong>di</strong> previsione a 2 bit. In uno<br />

schema a 2 bit <strong>la</strong> pre<strong>di</strong>zione deve essere sbagliata per due volte prima <strong>di</strong> essere<br />

mo<strong>di</strong>ficata. La Figura 3.12 mostra <strong>la</strong> macchina a stati finiti re<strong>la</strong>tiva a questo<br />

schema <strong>di</strong> previsione.<br />

Un buffer <strong>di</strong> pre<strong>di</strong>zione <strong>dei</strong> salti può essere realizzato come un piccolo buffer<br />

accessibile tramite l’in<strong>di</strong>rizzo dell’istruzione durante lo sta<strong>di</strong>o <strong>di</strong> fetch del<strong>la</strong><br />

pipeline. Se si pre<strong>di</strong>ce che il salto debba venire eseguito il caricamento viene<br />

effettuato a partire dall’in<strong>di</strong>rizzo destinazione non appena è noto il valore del<br />

PC; come detto in precedenza questo può avvenire già nello sta<strong>di</strong>o <strong>di</strong><br />

deco<strong>di</strong>fica, in caso contrario il caricamento e l’esecuzione in sequenza<br />

continuano. Se <strong>la</strong> pre<strong>di</strong>zione si rive<strong>la</strong> sbagliata i bit <strong>di</strong> pre<strong>di</strong>zione sono<br />

mo<strong>di</strong>ficati come mostrato nel<strong>la</strong> Figura 3.12.<br />

Un pregio <strong>di</strong> questo sistema è che i cicli vengono sempre accettati, e viene<br />

fallita solo <strong>la</strong> previsione re<strong>la</strong>tiva all’uscita del ciclo, mentre un sistema con<br />

contatori a bit singolo fallisce sia <strong>la</strong> prima che l’ultima istruzione.<br />

Esempi <strong>di</strong> unità <strong>di</strong> pre<strong>di</strong>zione molto gran<strong>di</strong> basate su questo sistema hanno<br />

ottenuto una percentuale <strong>di</strong> successo pari al 93,5% su benchmark SPEC.


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 71<br />

Pre<strong>di</strong>zione locale<br />

Preso<br />

Strongly taken<br />

(preso molto spesso)<br />

Preso<br />

Weakly not taken<br />

(non preso poco spesso)<br />

Non preso<br />

Preso<br />

Non preso<br />

Preso<br />

Weakly taken<br />

(preso poco spesso)<br />

Non preso<br />

Strongly not taken<br />

(non preso molto spesso)<br />

Non Preso .<br />

Figura 3.12- Gli stati possibili del<strong>la</strong> pre<strong>di</strong>zione bimodale<br />

La pre<strong>di</strong>zione bimodale fallisce all’uscita <strong>di</strong> ogni ciclo: per cicli che si ripetono<br />

con andamento sempre simile a sé stesso si può fare molto meglio.<br />

Con questo metodo ci si avvale <strong>di</strong> due tabelle. Una è in<strong>di</strong>cizzata con i bit meno<br />

significativi dell’istruzione re<strong>la</strong>tiva, e tiene traccia del<strong>la</strong> con<strong>di</strong>zione nelle ultime<br />

n esecuzioni. L’altra è una tabel<strong>la</strong> molto simile a quel<strong>la</strong> usata nel<strong>la</strong> pre<strong>di</strong>zione<br />

bimodale, ma è in<strong>di</strong>cizzata sul<strong>la</strong> base del<strong>la</strong> prima. Per effettuare una pre<strong>di</strong>zione,<br />

l’unità cerca, grazie al<strong>la</strong> prima tabel<strong>la</strong>, <strong>la</strong> parte del<strong>la</strong> seconda che tiene traccia<br />

del comportamento del<strong>la</strong> con<strong>di</strong>zione non in me<strong>di</strong>a, ma a quel punto del ciclo.<br />

Sui benchmark SPEC, sono stati ottenuti risultati intorno al 97,1%.<br />

Questa tecnica è più lenta perché richiede il controllo <strong>di</strong> due tabelle per<br />

effettuare ogni previsione. Una versione più veloce organizza un insieme<br />

separato <strong>di</strong> contatori bimodali per ogni istruzione a cui si accede; in questo<br />

modo il secondo accesso all’insieme può procedere in parallelo con l’accesso


72 Capitolo 3<br />

all’istruzione. Questi insiemi non sono ridondanti, in quanto ogni contatore<br />

traccia il comportamento <strong>di</strong> una singo<strong>la</strong> con<strong>di</strong>zione.<br />

Pre<strong>di</strong>zione globale<br />

Nel<strong>la</strong> pre<strong>di</strong>zione globale si fa affidamento sul fatto che il comportamento <strong>di</strong><br />

molte con<strong>di</strong>zioni si basa su quello <strong>di</strong> con<strong>di</strong>zioni vicine e valutate da poco. Si<br />

può così tenere un unico registro che tiene conto del comportamento <strong>di</strong> ogni<br />

con<strong>di</strong>zione valutata da poco, e usarne i valori per in<strong>di</strong>cizzare una tabel<strong>la</strong> <strong>di</strong><br />

contatori bimodali. Questo sistema è <strong>di</strong> per sé migliore del<strong>la</strong> pre<strong>di</strong>zione<br />

bimodale solo per gran<strong>di</strong> tabelle, e non è migliore del<strong>la</strong> pre<strong>di</strong>zione locale in<br />

nessun caso.<br />

Se invece si in<strong>di</strong>cizzano i contatori bimodali con <strong>la</strong> storia recente delle<br />

con<strong>di</strong>zioni concatenata ad alcuni bit dell’in<strong>di</strong>rizzo delle istruzioni si ottiene un<br />

previsore gselect, che supera <strong>la</strong> previsione locale in tabelle piccole e viene<br />

staccato <strong>di</strong> poco in tabelle maggiori <strong>di</strong> un KB.<br />

Si ottiene un metodo ancora migliore per le tabelle più gran<strong>di</strong> <strong>di</strong> 256 B, detto<br />

gshare, sostituendo nel gselect <strong>la</strong> concatenazione con l’operazione logica XOR.<br />

Quest’ultimo metodo ottiene nei benchmark un’efficienza del 96,6%, <strong>di</strong> poco<br />

inferiore al<strong>la</strong> pre<strong>di</strong>zione locale.<br />

Le pre<strong>di</strong>zioni globali sono più facili da rendere più veloci del<strong>la</strong> pre<strong>di</strong>zione<br />

locale in quanto richiedono in controllo <strong>di</strong> una so<strong>la</strong> tabel<strong>la</strong> per ogni previsione.<br />

Esistono altre tipologie <strong>di</strong> pre<strong>di</strong>zioni ma sono tecniche che richiedono un<br />

<strong>di</strong>spen<strong>di</strong>o <strong>di</strong> transistor eccessivo per le prestazioni che effettivamente offrono.<br />

Data l’importanza delle pre<strong>di</strong>zione <strong>dei</strong> salti comunque tutti i <strong>processori</strong> moderni


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 73<br />

implementano unità <strong>di</strong> pre<strong>di</strong>zione <strong>dei</strong> salti molto avanzate. Per esempio il<br />

POWER 5 prodotto da IBM implementa tre unità <strong>di</strong> pre<strong>di</strong>zione <strong>dei</strong> salti. Due<br />

unità cercano <strong>di</strong> pre<strong>di</strong>re i salti utilizzando strategie <strong>di</strong>verse e <strong>la</strong> terza unità tiene<br />

traccia delle percentuali <strong>di</strong> successo delle due unità e a seconda dell’istruzione<br />

sceglie l’unità che ha avuto <strong>la</strong> percentuale <strong>di</strong> successo maggiore.<br />

Esecuzione specu<strong>la</strong>tiva<br />

Per ridurre il problema delle alee <strong>di</strong> controllo, alcuni <strong>processori</strong> implementano<br />

un espe<strong>di</strong>ente chiamato esecuzione specu<strong>la</strong>tiva. Supponendo che un salto<br />

con<strong>di</strong>zionato <strong>di</strong>penda da <strong>dei</strong> dati non ancora e<strong>la</strong>borati, sul<strong>la</strong> base del<strong>la</strong> storia<br />

passata dell’istruzione <strong>di</strong> salto il processore effettua una previsione sul risultato<br />

del salto (specu<strong>la</strong>no sul possibile risultato) e carica le istruzioni conseguenti <strong>la</strong><br />

previsione. Questa tipologia <strong>di</strong> esecuzione richiede molti transistor per essere<br />

implementata perché oltre all’unita <strong>di</strong> specu<strong>la</strong>zione bisogna tener traccia delle<br />

istruzioni in esecuzioni che <strong>di</strong>pendono dal<strong>la</strong> specu<strong>la</strong>zione e, in caso <strong>di</strong> errata<br />

previsione, queste istruzioni vanno eliminate, mentre i loro effetti sui dati<br />

devono essere annul<strong>la</strong>ti.<br />

Ridenominazione <strong>dei</strong> registri:<br />

Alcune alee <strong>di</strong>pendo dal fatto che più istruzioni utilizzano gli stessi registri o le<br />

stesse locazioni <strong>di</strong> memoria, ad esempio per scrivere i risultati<br />

dell’e<strong>la</strong>borazione. Le due istruzioni seguenti:<br />

Istruzione 1:<br />

Istruzione 2:<br />

h = a + b<br />

h =<br />

c − d


74 Capitolo 3<br />

sono dal punto <strong>di</strong> vista <strong>dei</strong> dati in<strong>di</strong>pendenti, ma non possono essere scambiate<br />

dato che entrambe scrivono i risultati in h; invertendo le istruzioni al<strong>la</strong> fine<br />

dell’e<strong>la</strong>borazione si troverebbe il valore calco<strong>la</strong>to da “ a + b ” e non “ c − d ”,<br />

ottenendo un’esecuzione errata del programma. Questa non è una vera alea <strong>dei</strong><br />

dati, visto che in realtà le due istruzioni non sono realmente limitate dai dati ma<br />

sono limitate dai registri nei quali salvare i dati.<br />

I micro<strong>processori</strong> possono allora implementare <strong>la</strong> cosiddetta “ridenominazione<br />

<strong>dei</strong> registri”: in sostanza si introducono <strong>dei</strong> registri temporanei che vengono<br />

utilizzati per salvare i dati temporaneamente, in modo da poter eseguire le<br />

istruzioni in modo in<strong>di</strong>pendente; al<strong>la</strong> fine dell’esecuzione sarà l’unità <strong>di</strong><br />

ridenominazione a salvare nei registi reali i dati corretti. Nell’esempio visto<br />

sopra, il co<strong>di</strong>ce <strong>di</strong>verrebbe:<br />

Istruzione 1:<br />

Istruzione 2:<br />

Temp = a + b<br />

Temp<br />

1<br />

2<br />

= c − d<br />

Ciascuna istruzione salva i dati in un registro temporaneo, e quin<strong>di</strong> le due<br />

istruzioni possono essere eseguite in parallelo tanto al<strong>la</strong> fine l’unità <strong>di</strong><br />

ridenominazione provvederà a memorizzare in sequenza i dati nel registro h<br />

mantenendo <strong>la</strong> coerenza logica del programma. Lo scheduling <strong>di</strong>namico del<strong>la</strong><br />

pipeline e <strong>la</strong> ridenominazione <strong>dei</strong> registri permette <strong>di</strong> eliminare <strong>la</strong> maggior parte<br />

delle alee riducendo significativamente gli stalli nelle pipeline. L’utilizzo <strong>di</strong><br />

queste tecniche viene governato dall’algoritmo <strong>di</strong> Tomasulo o da sue varianti<br />

più moderne e efficienti.


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 75<br />

Sroto<strong>la</strong>mento <strong>di</strong>namico del loop<br />

Spesso i programmi sono formati da gruppi <strong>di</strong> istruzioni che vengono eseguite<br />

più volte in sequenza. Utilizzando le unità <strong>di</strong> scheduling <strong>di</strong>namico del<strong>la</strong> pipeline<br />

e <strong>di</strong> ridenominazione <strong>dei</strong> registri, i <strong>processori</strong> possono eseguire alcune istruzioni<br />

<strong>dei</strong> vari cicli in parallelo e possono eliminare alcuni salti con<strong>di</strong>zionati.<br />

Consideriamo per esempio il co<strong>di</strong>ce:<br />

Istruzione 1:<br />

Istruzione 2:<br />

Istruzione 3:<br />

Istruzione 4:<br />

a = 0<br />

FOR a <<br />

END<br />

dopo lo sroto<strong>la</strong>mento del loop ottengo:<br />

Istruzione I:<br />

Istruzione II:<br />

Istruzione III:<br />

Istruzione IV:<br />

Istruzione V:<br />

a = 0<br />

2<br />

k = k − d<br />

a = a + 1<br />

FOR<br />

k = k − d<br />

a = a + 1<br />

k = k − d<br />

a = a + 1<br />

Senza sroto<strong>la</strong>mento il processore dovrebbe eseguire 8 istruzioni (1 2 3 4 2 3 4<br />

2), delle quali tre sono salti con<strong>di</strong>zionati (l’istruzione 2). Dopo lo sroto<strong>la</strong>mento<br />

ottengo 5 istruzioni, i salti sono stati eliminati e le istruzioni possono essere<br />

eseguite dal<strong>la</strong> pipeline senza stalli.


76 Capitolo 3<br />

ILP STATICO<br />

ILP statico a <strong>di</strong>fferenza dell’ILP <strong>di</strong>namico viene eseguito durante <strong>la</strong> fase <strong>di</strong><br />

compi<strong>la</strong>zione del co<strong>di</strong>ce, il compi<strong>la</strong>tore analizza il co<strong>di</strong>ce rilevando le istruzioni<br />

parallelizzabili e le segna<strong>la</strong> in modo che durante l’esecuzione il processore<br />

sappia già quasi istruzioni sono parallelizzabili e come vadano eseguite. L’ILP<br />

statico è partico<strong>la</strong>rmente utilizzato dai <strong>processori</strong> embedded che per questioni <strong>di</strong><br />

costo e <strong>di</strong> consumi non possono implementare i complessi meto<strong>di</strong> <strong>di</strong> analisi<br />

richiesti dall’ILP <strong>di</strong>namico. Comunque l’ILP statico viene utilizzato in qualche<br />

modalità anche dai <strong>processori</strong> ad alte prestazioni: <strong>la</strong> famiglia <strong>di</strong> <strong>processori</strong><br />

Itanium, ad esempio è basata su questa filosofia.<br />

ILP statico, come l’ILP <strong>di</strong>namico, cerca <strong>di</strong> massimizzare le prestazioni<br />

utilizzando al massimo le pipeline minimizzandone gli stalli; questo viene<br />

ottenuto riorganizzando le istruzioni in un modo simile a quanto fa l’ILP<br />

<strong>di</strong>namico. Il compi<strong>la</strong>tore per poter produrre del co<strong>di</strong>ce efficiente deve conoscere<br />

nel dettaglio le caratteristiche del processore; deve conoscere dettagli come <strong>la</strong><br />

lunghezza delle pipeline, <strong>la</strong> loro organizzazione, i tempi <strong>di</strong> esecuzione, etc. Due<br />

<strong>processori</strong> con identico set <strong>di</strong> istruzioni (ISA) ma con <strong>di</strong>versa microarchitettura,<br />

eseguendo lo stesso co<strong>di</strong>ce con ottimizzazioni statiche, possono fornire<br />

prestazioni molto <strong>di</strong>verse. Un cambio <strong>di</strong> microarchitettura può richiedere una<br />

ricompi<strong>la</strong>zione del co<strong>di</strong>ce per poter sfruttare le reale prestazioni del<br />

microprocessore, cosa non necessaria con l’ILP <strong>di</strong>namico.


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 77<br />

L’ILP statico utilizza molte tecniche <strong>di</strong> analisi e <strong>di</strong> ottimizzazioni comuni a<br />

l’ILP <strong>di</strong>namico ma non dovendo eseguire le ottimizzazioni in tempo reale le<br />

analisi possono essere molto più approfon<strong>di</strong>te e quin<strong>di</strong> ottenere prestazioni<br />

migliori. Per esempio nel caso del<strong>la</strong> tecnica <strong>di</strong> sroto<strong>la</strong>mento <strong>dei</strong> loop il<br />

compi<strong>la</strong>tore analizzando il co<strong>di</strong>ce può riconoscere i loop e ottimizzandolo. Per<br />

esempio supponendo <strong>di</strong> avere del co<strong>di</strong>ce del tipo:<br />

Istruzione 1:<br />

Istruzione 2:<br />

Istruzione 3:<br />

Istruzione 4:<br />

i = 0<br />

FOR 1<<br />

1000<br />

END<br />

x [ i]<br />

= x[<br />

i]<br />

+ s<br />

i = i + 1<br />

FOR<br />

Il compi<strong>la</strong>tore riconoscendo il co<strong>di</strong>ce potrebbe notare che il loop viene eseguito<br />

mille volte e dato che <strong>la</strong> parte critica è il salto con<strong>di</strong>zionato (istruzione 2)<br />

potrebbe scrivere:<br />

Istruzione 1:<br />

Istruzione 2:<br />

Istruzione 3:<br />

Istruzione 4:<br />

Istruzione 5:<br />

Istruzione 6:<br />

i = 0<br />

FOR 1<<br />

1000<br />

x [ i]<br />

= x[<br />

i]<br />

+ s<br />

i = i + 1<br />

x [ i]<br />

= x[<br />

i]<br />

+ s<br />

i = i + 1<br />

END<br />

FOR


78 Capitolo 3<br />

Questo loop viene eseguito solo 500 volte dato che dentro un singolo loop sono<br />

state inserite le istruzioni che precedentemente venivano eseguite in due loop. Il<br />

proce<strong>di</strong>mento può essere iterato includendo altre istruzioni, riducendo così il<br />

numero <strong>di</strong> salti da eseguire; i salti infatti sono delle istruzioni che, dal punto <strong>di</strong><br />

vista del programma, non producono risultati utili, in quanto non influenzano<br />

<strong>di</strong>rettamente i dati ma solo il flusso del programma stesso. Il co<strong>di</strong>ce generato<br />

dallo sroto<strong>la</strong>mento del loop può essere migliorato eseguendo una<br />

ridenominazione <strong>dei</strong> registri e una riorganizzazione delle istruzioni che migliora<br />

le prestazioni. Per esempio il co<strong>di</strong>ce iniziale eseguito su un processore MIPS<br />

senza nessuna ottimizzazione richiede 10 cicli <strong>di</strong> clock per ogni loop;<br />

applicando le varie ottimizzazioni si ottiene un’esecuzione in 3.5 cicli <strong>di</strong> clock<br />

per ogni loop. Il compi<strong>la</strong>tore quando applica queste tecniche deve tenere conto<br />

anche <strong>dei</strong> problemi che queste portano. Lo sroto<strong>la</strong>mento del loop aumenta <strong>la</strong><br />

<strong>di</strong>mensione del co<strong>di</strong>ce e quin<strong>di</strong> <strong>la</strong> possibilità <strong>di</strong> non trovare i dati in cache;<br />

inoltre un eccessivo uso del<strong>la</strong> ridenominazione <strong>dei</strong> registri può terminare i<br />

registri temporanei costringendo il processore a utilizzare <strong>la</strong> lenta memoria <strong>di</strong><br />

sistema per salvare i registri non usati.<br />

L’ILP statico ovviamente cerca <strong>di</strong> sfruttare <strong>la</strong> presenza <strong>di</strong> più unità <strong>di</strong> calcolo:<br />

nell’esempio del loop, supponendo <strong>di</strong> avere un processore con due pipeline<br />

in<strong>di</strong>pendenti, si potrebbe ridurre il tempo <strong>di</strong> esecuzione da 3,5 cicli <strong>di</strong> clock per<br />

loop a 2,5 cicli <strong>di</strong> clock per loop.


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 79<br />

I <strong>processori</strong> che utilizzano l’ILP statico utilizzano generalmente meglio le<br />

pipeline: il compi<strong>la</strong>tore infatti può analizzare il co<strong>di</strong>ce in profon<strong>di</strong>tà e cercare<br />

l’organizzazione migliore delle istruzioni che ne massimizza l’utilizzo.<br />

Spesso questi compi<strong>la</strong>tori raggruppano le istruzioni in pacchetti che, una volta<br />

ricevuti dal processore, vengono semplicemente inviati alle pipeline; il<br />

processore non deve control<strong>la</strong>re alee o altro dato perché tutto è stato analizzato<br />

dal compi<strong>la</strong>tore e gli eventuali problemi sono già stati risolti. Questi <strong>processori</strong><br />

sono detti <strong>processori</strong> Very Long Instruction Word (VLIW).<br />

Nei <strong>processori</strong> VLIW il compi<strong>la</strong>tore esegue tutte le ottimizzazioni mentre il<br />

processore non fa altro che ricevere le istruzioni ed eseguirle quin<strong>di</strong> un<br />

processore VLIW è molto più semplice <strong>di</strong> un processore con ILP <strong>di</strong>namico <strong>di</strong><br />

pari velocità.<br />

Dipendendo in modo totale dal compi<strong>la</strong>tore per le prestazioni, i compi<strong>la</strong>tori<br />

utilizzano tecniche <strong>di</strong> analisi avanzate del co<strong>di</strong>ce per in<strong>di</strong>viduare il parallelismo<br />

intrinseco. Le principali sono:<br />

Tecniche pre<strong>di</strong>cative<br />

Le tecniche <strong>di</strong> analisi del co<strong>di</strong>ce funzionano bene quando si riesce a prevedere<br />

con un elevato margine <strong>di</strong> accuratezza il comportamento <strong>dei</strong> salti con<strong>di</strong>zionati. I<br />

salti con<strong>di</strong>zionati sono molto frequenti nel co<strong>di</strong>ce (me<strong>di</strong>amente ogni 7-10<br />

istruzioni si ha un salto) e possono ridurre le prestazioni delle architetture a<br />

pipeline in modo rilevante. Le tecniche <strong>di</strong> analisi statistiche funzionano bene nel


80 Capitolo 3<br />

caso <strong>di</strong> istruzioni <strong>di</strong> salto che si ripetono in modo rego<strong>la</strong>re (per esempio nei<br />

cicli) mentre negli altri casi i salti sono <strong>di</strong>fficilmente preve<strong>di</strong>bili. Per limitare<br />

l’impatto <strong>di</strong> questi salti si possono utilizzare le istruzioni pre<strong>di</strong>cative (o<br />

con<strong>di</strong>zionate). Le istruzioni pre<strong>di</strong>cative convertono una <strong>di</strong>pendenza dal<br />

controllo in una <strong>di</strong>pendenza sui dati eliminando in alcuni casi <strong>dei</strong> salti<br />

con<strong>di</strong>zionati <strong>di</strong>fficilmente preve<strong>di</strong>bili. Le istruzioni pre<strong>di</strong>cative sono delle<br />

normali istruzioni che però vengono eseguite se una certa con<strong>di</strong>zione è vera (o<br />

falsa a seconda <strong>dei</strong> casi). L’esempio più semplice (e comune) è <strong>la</strong> “move<br />

con<strong>di</strong>zionata”. Questa istruzione copia il valore <strong>di</strong> un registro in un altro<br />

registro se <strong>la</strong> con<strong>di</strong>zione associata è vera. Per esempio il co<strong>di</strong>ce<br />

if (A == 0) H = J<br />

verrebbe tradotto senza istruzioni con<strong>di</strong>zionate come:<br />

Istruzione 1:<br />

Istruzione 2:<br />

Se<br />

h =<br />

Istruzione 3: …<br />

a = 0<br />

Con le istruzioni con<strong>di</strong>zionate invece ottengo<br />

Istruzione 1:<br />

j<br />

salta a (2)<br />

a = 0 allora h = j 5<br />

altrimentisalta<br />

a (3)<br />

Il nuovo co<strong>di</strong>ce utilizza una so<strong>la</strong> istruzione quin<strong>di</strong> è più compatto ed inoltre<br />

elimina un salto; invece <strong>di</strong> un’istruzione <strong>di</strong> salto e <strong>di</strong> una “move” ho solo una<br />

5 Si par<strong>la</strong> <strong>di</strong> istruzioni pre<strong>di</strong>cative in quanto <strong>la</strong> con<strong>di</strong>zione <strong>di</strong> salto è stata sostituita da un<br />

pre<strong>di</strong>cato associato al<strong>la</strong> istruzione. In questo caso il pre<strong>di</strong>cato è <strong>la</strong> con<strong>di</strong>zione sul<strong>la</strong><br />

variabile “a”.


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 81<br />

“move con<strong>di</strong>zionata” che <strong>di</strong>pende unicamente dai dati: ho eliminato l’istruzione<br />

<strong>di</strong> salto che, essendo singo<strong>la</strong> e non legata a una qualche logica, è <strong>di</strong>fficile da<br />

prevedere. Questa strategia può essere estesa includendo praticamente tutte le<br />

istruzioni del processore; i <strong>processori</strong> Itanium per esempio possiedono istruzioni<br />

pre<strong>di</strong>cative che possono sostituire tutte le istruzioni c<strong>la</strong>ssiche (il processore è<br />

del tipo “full pre<strong>di</strong>cation”). Comunque <strong>la</strong> maggior parte <strong>dei</strong> <strong>processori</strong> si limita<br />

alle “move pre<strong>di</strong>cative” dato che negli altri casi l’utilizzo <strong>di</strong> istruzioni<br />

pre<strong>di</strong>cative aumenta <strong>la</strong> <strong>di</strong>mensione del processore senza necessariamente<br />

incrementare le prestazioni dello stesso.<br />

Le “move pre<strong>di</strong>cative” sono talmente utili che anche molti <strong>processori</strong> che<br />

implementano sofisticate tecniche <strong>di</strong> ILP <strong>di</strong>namico utilizzano anche questa<br />

tecnica per migliorare le prestazioni.<br />

L’approccio delle “istruzioni pre<strong>di</strong>cative” parte dal<strong>la</strong> constatazione che i<br />

micro<strong>processori</strong> moderni sono dotati <strong>di</strong> molte unità funzionali in grado <strong>di</strong><br />

eseguire operazioni in parallelo ma queste unità sono quasi sempre vuote.<br />

Processori anche molto complessi come il Pentium ® 4 pur potendo in teoria<br />

eseguire fino a 6 operazioni in contemporanea in realtà per <strong>la</strong> maggior parte del<br />

tempo eseguono una o due operazioni in parallelo. L’approccio pre<strong>di</strong>cativo<br />

punta a riempire al massimo le unità <strong>di</strong> e<strong>la</strong>borazioni eliminando poi in seguito le<br />

istruzioni eseguite ma non necessarie.


82 Capitolo 3<br />

Very Long Instruction Word<br />

Le architetture Very Long Instruction Word sono basate sull’utilizzo del<br />

parallelismo intrinseco presente delle istruzioni. Similmente ai micro<strong>processori</strong><br />

supersca<strong>la</strong>ri queste CPU sono dotate <strong>di</strong> più unità <strong>di</strong> calcolo in<strong>di</strong>pendenti (per<br />

esempio due moltiplicatori) per permettere al<strong>la</strong> CPU <strong>di</strong> eseguire più calcoli<br />

contemporaneamente (per esempio due moltiplicazioni).<br />

Progetto<br />

In un progetto supersca<strong>la</strong>re il numero <strong>di</strong> unità <strong>di</strong> calcolo non è visibile nel set <strong>di</strong><br />

istruzioni. Ogni istruzione co<strong>di</strong>fica una so<strong>la</strong> istruzione, e per molti<br />

micro<strong>processori</strong> sono lunghe 32 bit o meno.<br />

Invece ogni istruzione VLIW co<strong>di</strong>fica più istruzioni elementari specificando<br />

una istruzione per ogni unità <strong>di</strong> calcolo. Per esempio un <strong>di</strong>spositivo VLIW con<br />

5 unità <strong>di</strong> calcolo sarà dotato <strong>di</strong> istruzioni con cinque campi, ognuno specifico<br />

per ogni unità <strong>di</strong> calcolo. Ovviamente le istruzioni VLIW sono molto più lunghe<br />

delle c<strong>la</strong>ssiche istruzioni: sono lunghe almeno 64 bit ma spesso sono <strong>di</strong> 128 bit<br />

o più.<br />

Sin dalle prime architetture ci si è resi conto che aggiungendo unità <strong>di</strong> calcolo<br />

alle macchine si potevano incrementare le prestazioni senza aumentare i costi in<br />

maniera eccessiva. Nelle CPU supersca<strong>la</strong>ri è <strong>la</strong> CPU stessa che durante<br />

l’esecuzione decide <strong>di</strong>namicamente quali istruzioni mandare in esecuzione in<br />

parallelo. nelle CPU VLIW è il compi<strong>la</strong>tore che durante <strong>la</strong> fase <strong>di</strong> traduzione<br />

decide quali istruzioni vadano eseguite in parallelo.


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 83<br />

Per esempio, una CPU può essere in grado <strong>di</strong> eseguire due moltiplicazioni<br />

contemporaneamente. Supponendo che <strong>la</strong> CPU riceva le due moltiplicazioni, <strong>la</strong><br />

prima sarà mandata in esecuzione nel<strong>la</strong> prima unità ma se <strong>la</strong> seconda<br />

moltiplicazione <strong>di</strong>pendesse dal risultato del<strong>la</strong> prima questa non potrebbe essere<br />

mandata in esecuzione e al suo posto verrebbe effettuato un blocco in hardware.<br />

In un’istruzione VLIW il compi<strong>la</strong>tore in<strong>di</strong>viduerebbe il conflitto e introdurrebbe<br />

una NOP per <strong>la</strong> seconda unità <strong>di</strong> calcolo. Questo riduce <strong>la</strong> complessità del<strong>la</strong><br />

CPU.<br />

Inoltre un compi<strong>la</strong>tore VLIW può riconoscere il problema delle due<br />

moltiplicazioni e quin<strong>di</strong> anticipare una istruzione che non ha precon<strong>di</strong>zioni per<br />

poter incrementare le prestazioni del<strong>la</strong> CPU evitando l’utilizzo dell’istruzione<br />

NOP. Un simile approccio viene seguito anche da alcune CPU supersca<strong>la</strong>ri<br />

moderne che però, dovendo eseguire queste decisioni in tempo reali, forniscono<br />

un modesto miglioramento delle prestazioni a fronte <strong>di</strong> un importante<br />

incremento del<strong>la</strong> complessità del progetto.<br />

Un simile problema si presenta se il risultato <strong>di</strong> un’istruzione viene utilizzato<br />

per definire se uscire da un ciclo o no. Molte CPU moderne scelgono in anticipo<br />

un percorso in modo da poter caricare i dati corrispondente. Alcune CPU sono<br />

dotate <strong>di</strong> una unità <strong>di</strong> pre<strong>di</strong>zione delle <strong>di</strong>ramazioni che effettua una analisi del<br />

co<strong>di</strong>ce per prevedere <strong>la</strong> <strong>di</strong>ramazione più probabile. Questi meto<strong>di</strong> incrementano<br />

<strong>la</strong> complessità del progetto e corrompono <strong>la</strong> filosofia originaria delle<br />

architetture RISC anche perché <strong>la</strong> CPU deve contenere anche l’elettronica che


84 Capitolo 3<br />

in caso <strong>di</strong> errore del<strong>la</strong> pre<strong>di</strong>zione elimina le istruzioni in esecuzione e elimina le<br />

eventuali mo<strong>di</strong>fiche già eseguite.<br />

In un’architettura VLIW il compi<strong>la</strong>tore utilizza delle euristiche o <strong>dei</strong> profili per<br />

predeterminare in anticipo il ramo più probabile. Avendo il compi<strong>la</strong>tore molto<br />

più tempo del<strong>la</strong> CPU e <strong>la</strong> possibilità <strong>di</strong> analizzare tutto il co<strong>di</strong>ce invece che solo<br />

qualche istruzione, le sue previsioni sono molto più precise <strong>di</strong> quelle effettuate<br />

da una CPU in tempo reale. Comunque il compi<strong>la</strong>tore sviluppa il co<strong>di</strong>ce con il<br />

ramo più probabile già co<strong>di</strong>ficato nel co<strong>di</strong>ce e fornisce anche il co<strong>di</strong>ce per<br />

eliminare le istruzioni già eseguite nel caso <strong>la</strong> previsione non sia quel<strong>la</strong> corretta.<br />

Problematiche<br />

Il principale problema <strong>di</strong> questa architettura è l’estrema <strong>di</strong>pendenza <strong>dei</strong><br />

programmi dal compi<strong>la</strong>tore. Un programma ottimizzato per un processore<br />

VLIW per <strong>la</strong>vorare in modo efficiente sul<strong>la</strong> generazione successiva <strong>di</strong><br />

micro<strong>processori</strong> va quasi sempre ricompi<strong>la</strong>to. Questo rende problematico per un<br />

utente cambiare il computer, dato che anche il suo parco software andrebbe<br />

adattato al nuovo processore, a meno che i programmi non siano scritti con un<br />

linguaggio come il Java che, essendo in realtà compi<strong>la</strong>to durante l’esecuzione,<br />

possa essere adattato al<strong>la</strong> macchina durante l’esecuzione. Un’altra strategia è<br />

utilizzare uno strato software che interpreti il vecchio co<strong>di</strong>ce e lo adatti al nuovo<br />

processore ma in questo caso si ha un deperimento delle prestazioni che può<br />

essere anche molto marcato. Questa strategia viene utilizzata per esempio dal<br />

processore Efficeon del<strong>la</strong> Transmeta che interpreta co<strong>di</strong>ce <strong>Intel</strong> ® x86 standard e<br />

internamente lo traduce in co<strong>di</strong>ce VLIW per <strong>la</strong> CPU.


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 85<br />

Evoluzioni<br />

L’architettura VLIW ha indubbiamente molti vantaggi ma i suoi problemi ne<br />

rendono problematico l’utilizzo in <strong>processori</strong> per computer. La necessita <strong>di</strong><br />

ricompi<strong>la</strong>re il co<strong>di</strong>ce per ogni generazione <strong>di</strong> <strong>processori</strong> in partico<strong>la</strong>re si scontra<br />

con <strong>la</strong> necessita degli utenti <strong>di</strong> poter mantenere il parco software. Per eliminare<br />

questi problemi <strong>di</strong>verse società hanno sviluppato delle <strong>evoluzioni</strong><br />

dell’architettura VLIW, tra le varie <strong>evoluzioni</strong> <strong>la</strong> più famosa è l’architettura<br />

EPIC sviluppata da <strong>Intel</strong> ® e Hewlett-Packard ® congiuntamente <strong>di</strong> cui<br />

accenneremo nel paragrafo 5.4.4. L’architettura EPIC (Explicitly Parallel<br />

Instruction Computing) raggruppa le istruzioni elementari in parole come una<br />

c<strong>la</strong>ssica architettura VLIW e inserisce inoltre delle informazioni sul<br />

parallelismo tra le varie parole. In questo modo le varie generazioni del<br />

processore possono variare internamente <strong>la</strong> loro architettura senza troppi<br />

problemi. Le informazioni sul parallelismo permettono <strong>di</strong> realizzare unità <strong>di</strong><br />

deco<strong>di</strong>fica che sfruttano il parallelismo efficientemente ma sono nel contempo<br />

semplici dato che l’analisi del co<strong>di</strong>ce parallelo e <strong>la</strong> sua sud<strong>di</strong>visione è stata<br />

effettuata dal compi<strong>la</strong>tore.<br />

Caricamento specu<strong>la</strong>tivo<br />

Nei primi capitoli abbiamo visto come i <strong>processori</strong> siano <strong>di</strong>ventati sempre più<br />

veloci e nel giro <strong>di</strong> un decennio siano passati da frequenze <strong>di</strong> poche decine <strong>di</strong><br />

Megahertz a frequenze <strong>di</strong> funzionamento dell’or<strong>di</strong>ne <strong>dei</strong> Gigahertz. Le memorie<br />

invece non sono <strong>di</strong>ventate altrettanto veloci.


86 Capitolo 3<br />

Figura 3.13 - Crescita del GAP tra <strong>la</strong> velocità delle memorie e delle CPU<br />

I <strong>processori</strong> per limitare il problema hanno implementato cache <strong>di</strong> primo,<br />

secondo e a volte anche <strong>di</strong> terzo livello. La presenza delle cache con gli ultimi<br />

<strong>processori</strong> non è più sufficiente per evitare un eccessivo deperimento delle<br />

prestazioni.<br />

Un metodo per migliorare le prestazioni può essere allora quello del<br />

“caricamento specu<strong>la</strong>tivo”: il compi<strong>la</strong>tore, analizzando il co<strong>di</strong>ce, potrebbe<br />

in<strong>di</strong>viduare delle istruzioni o <strong>dei</strong> dati che probabilmente verranno richiesti e<br />

quin<strong>di</strong> porre delle load specu<strong>la</strong>tive. Queste load caricano i dati o le istruzioni<br />

prima del<strong>la</strong> loro effettiva richiesta eliminando o comunque limitando i tempi <strong>di</strong><br />

caricamento dal<strong>la</strong> memoria.<br />

Il precaricamento <strong>dei</strong> dati e delle istruzioni introduce <strong>dei</strong> problemi.<br />

Ad esempio se i dati caricati venissero mo<strong>di</strong>ficati prima del loro reale utilizzo.<br />

Occorre allora che, in tutti i casi <strong>di</strong> scrittura, il processore controlli se le celle<br />

scritte erano state caricate in modo specu<strong>la</strong>tivo e in tal caso eliminarle in modo<br />

da evitare incoerenze <strong>di</strong> esecuzione.


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 87<br />

Se invece il microprocessore carica delle istruzioni <strong>di</strong>pendenti da un salto e quel<br />

salto non viene eseguito, il processore deve provvedere ad eliminare le<br />

istruzioni caricate erroneamente prima <strong>di</strong> caricare le istruzioni da eseguire.<br />

Problemi anche maggiori si hanno nel caso <strong>di</strong> generazione <strong>di</strong> un’eccezione, per<br />

esempio l’accesso a una locazione non consentita genera una eccezione che va<br />

segna<strong>la</strong>ta al sistema operativo, ma <strong>la</strong> segna<strong>la</strong>zione va effettuata quando<br />

dovrebbe effettivamente avere luogo e non prima per via del precaricamento.<br />

Questi problemi rendono il precaricamento <strong>dei</strong> dati e delle istruzioni molto<br />

complesso da implementare in hardware senza un supporto <strong>di</strong>retto del set <strong>di</strong><br />

istruzioni. Invece se il set <strong>di</strong> istruzioni supporta nativamente questa<br />

caratteristica <strong>la</strong> sua gestione <strong>di</strong>venta molto più semplice.<br />

Altre tecniche <strong>di</strong> ottimizzazione<br />

Static branch pre<strong>di</strong>ction<br />

Il compi<strong>la</strong>tore cerca <strong>di</strong> prevedere il risultato <strong>dei</strong> salti (branch) tramite analisi<br />

statistiche del co<strong>di</strong>ce in modo da mantenere le pipeline sempre cariche. Queste<br />

tecniche ricalcano quelle applicate dai <strong>processori</strong> con ILP <strong>di</strong>namico ma in<br />

questo caso forniscono me<strong>di</strong>amente prestazioni inferiori dato che il processore è<br />

in grado <strong>di</strong> adeguarsi all’esecuzione <strong>di</strong>namica del programma mentre il<br />

compi<strong>la</strong>tore non può prevedere come il programma si comporterà durante<br />

l’esecuzione.<br />

Loop Level Parallelism.


88 Capitolo 3<br />

Questa tecniche cerca <strong>di</strong> in<strong>di</strong>viduare il parallelismo tra iterazioni successive del<br />

loop nel caso <strong>di</strong> loop con cicli non in<strong>di</strong>pendenti.<br />

Symbolic loop unrolling.<br />

Con questa tecnica si decide <strong>di</strong> non sroto<strong>la</strong>re i loop ma <strong>di</strong> aggiungervi<br />

all’interno delle istruzioni in<strong>di</strong>pendenti in modo da evitare stallo durante<br />

l’esecuzione.<br />

Global code scheduling.<br />

Questa tecnica analizza il co<strong>di</strong>ce al<strong>la</strong> ricerca <strong>di</strong> istruzioni in<strong>di</strong>pendenti;<br />

l’esplorazione prosegue anche se il compi<strong>la</strong>tore trova delle istruzioni<br />

con<strong>di</strong>zionate (come salti o cicli).<br />

3.2.2 Multithrea<strong>di</strong>ng<br />

Un altro modo per parallelizzare l’esecuzione <strong>di</strong> co<strong>di</strong>ce è quello <strong>di</strong> sud<strong>di</strong>videre<br />

il programma in thread, ovvero due o più task che possono essere eseguiti in<br />

modo concorrente. L’implementazione <strong>dei</strong> thread e <strong>dei</strong> processi viene gestita in<br />

modo <strong>di</strong>verso a seconda del sistema operativo ma, in generale, si può <strong>di</strong>re che<br />

un thread è contenuto all’interno <strong>di</strong> un processo e che <strong>di</strong>versi thread contenuti<br />

nello stesso processo con<strong>di</strong>vidono alcune risorse (spesso <strong>la</strong> memoria del<br />

computer), mentre processi <strong>di</strong>fferenti non con<strong>di</strong>vidono risorse.<br />

La sud<strong>di</strong>visione <strong>dei</strong> programmi in thread può essere utilizzata sia in architetture<br />

multiprocessore che a singolo processore.


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 89<br />

Nelle architetture a processore singolo quando <strong>la</strong> CPU esegue alternativamente<br />

istruzioni <strong>di</strong> thread <strong>di</strong>fferenti si par<strong>la</strong> <strong>di</strong> multithrea<strong>di</strong>ng a <strong>di</strong>visione <strong>di</strong> tempo. La<br />

commutazione fra i thread avviene <strong>di</strong> solito tanto frequentemente da dare<br />

all’utente l’impressione che tutti i task siano eseguiti contemporaneamente.<br />

Nelle architetture multi-processore i thread vengono invece realmente eseguiti<br />

contemporaneamente, ciascuno su un <strong>di</strong>stinto processore.<br />

Figura 3.14 - Un processore single thread esegue un solo thread per volta<br />

Figura 3.15 -Un sistema multiprocessore c<strong>la</strong>ssico esegue un thread per unità <strong>di</strong> calcolo


90 Capitolo 3<br />

Figura 3.16 - Un sistema superthrea<strong>di</strong>ng schedu<strong>la</strong> più thread ma ne esegue uno solo<br />

per ciclo <strong>di</strong> clock<br />

CENNI STORICI<br />

Il para<strong>di</strong>gma del multithear<strong>di</strong>ng è <strong>di</strong>ventato molto popo<strong>la</strong>re verso <strong>la</strong> fine degli<br />

anni novanta quando le ricerche sull’incremento dell’Instruction Level<br />

Parallelism si sono bloccate. Allora l’attenzione si è spostata dall’eseguire un<br />

singolo programma al<strong>la</strong> massima velocità, all’occupare con <strong>la</strong> massima<br />

efficienza possibile le unità <strong>di</strong> calcolo. Si è appurato che molti programmi erano<br />

composti da più thread paralleli o potevano essere scomposti in più thread<br />

paralleli con lievi mo<strong>di</strong>fiche al co<strong>di</strong>ce sorgente. Quin<strong>di</strong> migliorando<br />

l’esecuzione <strong>di</strong> thread paralleli si poteva migliorare l’esecuzione complessiva<br />

<strong>dei</strong> programmi. Questo ha spinto lo sviluppo <strong>dei</strong> sistemi multithrea<strong>di</strong>ng e <strong>dei</strong><br />

sistemi multiprocessore.


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 91<br />

TIPI DI MULTITHREADING<br />

Possiamo in<strong>di</strong>viduare tre tipologie <strong>di</strong> Multithrea<strong>di</strong>ng:<br />

• Coarse-Grained Multithrea<strong>di</strong>ng (CMT)<br />

• Fine-Grained Multithrea<strong>di</strong>ng (FMT)<br />

• Simultaneous Multithrea<strong>di</strong>ng (SMT)<br />

COARSE-GRAINED MULTITHREADING<br />

Idea <strong>di</strong> base<br />

Il multithrea<strong>di</strong>ng coarse-grained (a grana grossa) è detto anche Block or<br />

Cooperative multithrea<strong>di</strong>ng.<br />

Esso prevede che il processore esegua un singolo thread fino a quando questo<br />

non viene bloccato da un evento che normalmente ha una elevata <strong>la</strong>tenza (per<br />

esempio un cache miss), in questo caso il processore provvede a eseguire un<br />

altro thread che era pronto per l’esecuzione. Il thread <strong>di</strong> rimpiazzo rimane in<br />

esecuzioni fino a quando il primo thread non è pronto per l’esecuzione.<br />

Per esempio:<br />

Ciclo i : l’istruzione j del thread A viene caricata<br />

Ciclo i+1 : l’istruzione j+1 del thread A viene caricata<br />

Ciclo i+2 : l’istruzione j+2 del thread A viene caricata, il<br />

caricamento provoca un cache miss con<br />

corrispondente richiesta nel<strong>la</strong> memoria centrale<br />

Ciclo i+3 : il processore avvia l’esecuzione del thread B<br />

Ciclo i+4 : l’istruzione k del thread B viene caricata<br />

Ciclo i+5 : l’istruzione k+1 del thread B viene caricata


92 Capitolo 3<br />

Costo hardware<br />

Il multithrea<strong>di</strong>ng parte dal presupposto che il passaggio tra thread avvenga in<br />

modo rapido, questa tecnica effettua il passaggio in un ciclo <strong>di</strong> clock. Al fine <strong>di</strong><br />

ottenere questo risultato, il processore deve replicare alcune componenti per i<br />

due thread come i registri interni, il program counter e alcuni registri <strong>di</strong> stato.<br />

Anche gli adattamenti a livello software sono re<strong>la</strong>tivamente modesti dato che il<br />

sistema operativo deve gestire un numero modesto <strong>di</strong> thread in esecuzione<br />

contemporanea.<br />

FINE-GRAINED MULTITHREADING<br />

Idea <strong>di</strong> base<br />

Questa tecnica <strong>di</strong> multithrea<strong>di</strong>ng inizialmente venne chiamata “barrel<br />

processing” ma attualmente <strong>la</strong> terminologia moderna definisce questa tecnica<br />

come “pre-empiteve” o “inter<strong>la</strong>ved” o “time-sliced” o “fine-grained<br />

multithrea<strong>di</strong>ng”.<br />

Si tratta <strong>di</strong> una tipologia <strong>di</strong> multithrea<strong>di</strong>ng molto spinto e prevede che il<br />

processore scambi il thread in esecuzione a ogni ciclo <strong>di</strong> clock.<br />

Per esempio:<br />

Ciclo i : l’istruzione j del thread A viene caricata<br />

Ciclo i+1: l’istruzione k del thread B viene caricata<br />

Ciclo i+2: l’istruzione h del thread C viene caricata<br />

Questa tipologia <strong>di</strong> mutithrea<strong>di</strong>ng dovrebbe rimuovere <strong>la</strong> <strong>di</strong>pendenza dai dati<br />

<strong>dei</strong> singoli thread e quin<strong>di</strong> dovrebbe azzerare o comunque ridurre gli stalli del<strong>la</strong><br />

pipeline dovuta al<strong>la</strong> <strong>di</strong>pendenza dai dati. Dato che ogni thread dovrebbe


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 93<br />

funzionare in modo in<strong>di</strong>pendente, i singoli thread eseguiranno programmi non<br />

corre<strong>la</strong>ti e quin<strong>di</strong> vi saranno poche probabilità che le istruzioni <strong>di</strong> un thread<br />

necessitino <strong>dei</strong> risultati e<strong>la</strong>borati da un’istruzione <strong>di</strong> un altro thread in<br />

esecuzione in quel momento.<br />

Concettualmente questa tecnica è simile al “multitasking pre-emptive” presente<br />

in molti sistemi operativi. Questa analogia parte dal presupposto che ogni slot <strong>di</strong><br />

tempo <strong>dei</strong> programmi sia posto uguale a un ciclo <strong>di</strong> clock del processore.<br />

Costo hardware<br />

In aggiunta alle componenti in<strong>di</strong>cate precedentemente questa tecnica <strong>di</strong><br />

multithrea<strong>di</strong>ng richiede delle componenti aggiuntive che assegnino a ogni<br />

istruzione in esecuzione un’ID che ne permetta <strong>di</strong> identificare il thread<br />

proprietario. Questa tecnica richiede che lo scambio tra i thread avvenga senza<br />

cicli <strong>di</strong> clock <strong>di</strong> stallo e quin<strong>di</strong> richiede hardware più sofisticato; inoltre <strong>la</strong><br />

presenza <strong>di</strong> molti thread in esecuzione in parallelo, richiede generalmente cache<br />

e TLB più capienti, al fine <strong>di</strong> poter servire i vari thread in modo efficiente.<br />

SIMULTANEOUS MULTI-THREADING<br />

Idea <strong>di</strong> base<br />

Per <strong>di</strong>stinguerlo degli altri tipi <strong>di</strong> multithrea<strong>di</strong>ng il termine “temporal<br />

multithrea<strong>di</strong>ng” in<strong>di</strong>ca un tipo <strong>di</strong> multithrea<strong>di</strong>ng che permette il completamento<br />

<strong>di</strong> istruzioni <strong>di</strong> un solo thread per ciclo <strong>di</strong> clock.<br />

I moderni <strong>processori</strong> hanno più unità <strong>di</strong> calcolo che vengono utilizzate<br />

eseguendo le istruzioni <strong>dei</strong> singoli thread in parallelo. Gli attuali <strong>processori</strong>


94 Capitolo 3<br />

sono in grado <strong>di</strong> eseguire so<strong>la</strong>mente poche istruzioni in parallelo <strong>di</strong> un signolo<br />

thread per via del ridotto parallelismo a livello <strong>di</strong> istruzioni che normalmente i<br />

thread possiedono. Spesso perciò alcune unità <strong>di</strong> e<strong>la</strong>borazione rimangono<br />

inutilizzate durante le e<strong>la</strong>borazioni. Per evitare questo, il Simultaneous Multi-<br />

threa<strong>di</strong>ng (SMT) esegue più thread in contemporanea e utilizza le istruzioni <strong>dei</strong><br />

singoli thread per mantenere le unità <strong>di</strong> e<strong>la</strong>borazione sempre operative.<br />

Per esempio:<br />

Costo hardware<br />

Ciclo i: istruzione j e j+1 dal thread A, istruzione k dal<br />

thread B, tutte eseguite in simultanea<br />

Ciclo i+1: istruzione j+2 dal thread A, istruzione k+1 dal<br />

thread B, istruzione m dal thread C, eseguite in<br />

simultanea<br />

Ciclo i+2: istruzione j+3 dal thread A, istruzione m+1 e<br />

m+2 dal thread C, eseguite in simultanea.<br />

In aggiunta all’hardware richiesto dal precedente multithrea<strong>di</strong>ng, questa tecnica<br />

richiede che ogni sta<strong>di</strong>o del<strong>la</strong> pipeline tracci il thread d’appartenenza<br />

dell’istruzione e dato che il processore ha più unità d’esecuzione vi sono molte<br />

istruzioni da tracciare. Inoltre <strong>la</strong> cache e <strong>la</strong> TLB deve essere molto ampia per<br />

poter gestire un numero <strong>di</strong> thread molto elevato che eseguendo più istruzioni in<br />

parallelo fanno un uso molto intenso delle risorse suddette.


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 95<br />

Figura 3.17 - Un sistema Simultaneous Multi-Threa<strong>di</strong>ng schedu<strong>la</strong> più thread e ne<br />

esegue in contemporaneo le istruzioni al fine <strong>di</strong> occupare al meglio le unità<br />

d’e<strong>la</strong>borazione<br />

3.2.3 Multi core<br />

Il termine “multi core” si usa per descrivere una CPU composta da 2 o più core,<br />

ovvero da più “cuori” <strong>di</strong> <strong>processori</strong> fisici montati sullo stesso package.<br />

TECNICHE DI REALIZZAZIONE<br />

Al momento, esistono 3 meto<strong>di</strong> <strong>di</strong>fferenti per creare un chip dual core:<br />

• Die 6<br />

Singolo<br />

• Die Doppio<br />

• Die Monolitico<br />

6<br />

Il "Die" è il blocco <strong>di</strong> silicio al centro <strong>di</strong> un processore che contiene il cuore<br />

e<strong>la</strong>borativo del<strong>la</strong> CPU, il core.


96 Capitolo 3<br />

DIE SINGOLO<br />

È l’approccio senz’altro più semplice, e quin<strong>di</strong> più economico rispetto agli altri,<br />

per realizzare un chip dual core ma, ovviamente, è anche più limitante per<br />

quanto riguarda le prestazioni e <strong>la</strong> resa produttiva.<br />

In maniera un po’ semplicistica, possiamo <strong>di</strong>re che per realizzarlo è sufficiente<br />

utilizzare <strong>la</strong> stessa maschera litografica <strong>di</strong>segnata per un processore single core,<br />

e “stampar<strong>la</strong>” 2 volte sul wafer <strong>di</strong> silicio interconnettendo i due core così<br />

realizzati. Rimane comunque il problema che se anche solo uno <strong>dei</strong> 2 core<br />

stampati è <strong>di</strong>fettoso, tutto il chip <strong>di</strong>venta inutilizzabile 7<br />

L’evoluzione delle tecniche produttive probabilmente ha già decretato <strong>la</strong><br />

“morte” <strong>di</strong> tale approccio, che sebbene semplice da realizzare può risultare<br />

in<strong>di</strong>rettamente costoso per <strong>la</strong> probabilità <strong>di</strong> non avere molti core attigui sul<br />

wafer perfettamente funzionanti.<br />

DIE DOPPIO<br />

Tale metodo consiste nel posizionare 2 <strong>di</strong>e, fisicamente separati, su un unico<br />

package e collegarli successivamente con collegamenti esterni. Tale metodo è<br />

<strong>legge</strong>rmente più complesso nel<strong>la</strong> realizzazione <strong>di</strong> quello a <strong>di</strong>e Singolo, in<br />

quanto collegare i core in un secondo momento richiede maggiore tempo che<br />

realizzare i collegamenti <strong>di</strong>rettamente sul silicio. Esso però risulta<br />

complessivamente il metodo più economico dal punto <strong>di</strong> vista del produttore:<br />

infatti è possibile “scegliere” quali devono essere i due core che andranno poi<br />

7 In questo caso il processore potrebbe essere rivenduto come semplice single core dopo<br />

aver opportunamente <strong>di</strong>sabilitato il core non funzionante.


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 97<br />

collegati insieme, facendo cadere <strong>la</strong> necessità <strong>dei</strong> due core affiancati e<br />

massimizzando <strong>la</strong> resa produttiva.<br />

Soprattutto agli albori dell'utilizzo <strong>di</strong> quest’approccio i chip che superavano i<br />

test, venivano valutati sui margini <strong>di</strong> clock e tensioni; i modelli che tolleravano<br />

frequenze <strong>di</strong> clock elevate potevano essere marchiati come veloci <strong>processori</strong><br />

single core, mentre gli altri potevano essere accoppiati per realizzare i modelli<br />

dual core che generalmente funzionavano a clock inferiori.<br />

C’è tuttavia un grande svantaggio nell'inserire due core in<strong>di</strong>pendenti in un solo<br />

package. Quando un core accede ai dati, anche l’altro farà lo stesso, utilizzando<br />

risorse non necessarie.<br />

DIE MONOLITICO<br />

L'approccio a “Die Monolitico” è certamente quello più sofisticato da realizzare<br />

ma ovviamente è anche quello che garantisce le migliori prestazioni <strong>di</strong> una CPU<br />

multi core. Tale approccio deve essere preventivato fin dalle prime fasi del<strong>la</strong><br />

progettazione del processore. Il suo più grande pregio consiste nell'offrire ai<br />

progettisti l'opportunità <strong>di</strong> con<strong>di</strong>videre alcune unità del processore; nel caso più<br />

semplice, tale con<strong>di</strong>visione si limita al<strong>la</strong> cache che viene realizzata in un unico<br />

blocco con<strong>di</strong>viso tra tutti i core 8<br />

. In casi più complessi le unità con<strong>di</strong>vise<br />

possono essere anche altre, come il controller del<strong>la</strong> memoria RAM, gli<br />

scheduler che ripartiscono il carico tra i vari core, ecc.<br />

8 in <strong>processori</strong> che utilizzano gli altri approcci costruttivi, <strong>la</strong> cache è necessariamente<br />

equamente <strong>di</strong>visa tra i core e l'accesso <strong>di</strong>retto a ciascuna cache è riservato<br />

esclusivamente al rispettivo core, il quale per accedere alle altre deve far transitare i dati<br />

sul BUS


98 Capitolo 3<br />

Tutti i più recenti progetti <strong>di</strong> <strong>processori</strong> multi core puntano soprattutto<br />

all'utilizzo <strong>di</strong> quest'ultimo approccio costruttivo, riservando gli altri (soprattutto<br />

quello a <strong>di</strong>e doppio), per risolvere specifiche esigenze.<br />

COME REALIZZARE CHIP MULTI CORE<br />

Analogamente ai <strong>di</strong>fferenti meto<strong>di</strong> appena esposti per realizzare un chip dual<br />

core, anche per quelli multi core è possibile utilizzare gli stessi <strong>di</strong>versi approcci.<br />

In questo caso però è anche possibile “combinare” i meto<strong>di</strong> per ottimizzare <strong>la</strong><br />

produzione a seconda delle esigenze <strong>dei</strong> progettisti e del mercato.<br />

3.2.4 Parallelismo <strong>dei</strong> dati e Unità Vettoriali<br />

IDEA DI BASE<br />

Un processore vettoriale o “array processor” è una CPU progettata per svolgere<br />

operazioni matematiche su più dati elementari contemporaneamente. Questo in<br />

contrasto con l’architettura c<strong>la</strong>ssica <strong>di</strong> un processore sca<strong>la</strong>re che prevede<br />

l’e<strong>la</strong>borazione <strong>di</strong> un singolo dato per volta. La maggior parte <strong>dei</strong> <strong>processori</strong><br />

sono sca<strong>la</strong>ri (o esternamente lo sembrano). I <strong>processori</strong> vettoriali sono comuni<br />

nelle applicazioni scientifiche e sono spesso al<strong>la</strong> base <strong>dei</strong> supercomputer fin<br />

dagli anni 80. Con <strong>la</strong> fine degli anni 90 i micro<strong>processori</strong> sono cresciuti <strong>di</strong><br />

prestazioni e molti <strong>processori</strong> per applicazioni generiche si sono dotati <strong>di</strong> unità<br />

vettoriali o sono <strong>di</strong>ventati vettoriali al loro interno. Nel 2000 IBM Toshiba e<br />

Sony hanno iniziato lo sviluppo del processore Cell, un microprocessore ad


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 99<br />

elevate prestazioni dotato <strong>di</strong> svariate unità vettoriali e rivolto ad applicazioni<br />

che spaziano dalle consolle al supercalcolo.<br />

Attualmente praticamente ogni CPU moderna include istruzioni vettoriali<br />

tipicamente conosciute come istruzioni SIMD. Le consolle per i videogiochi e<br />

le schede grafiche fanno un ampio uso <strong>di</strong> <strong>processori</strong> vettoriali dato che<br />

l’e<strong>la</strong>borazione <strong>di</strong> flussi au<strong>di</strong>o e video in tempo reale è un campo che ben si<br />

presta all’e<strong>la</strong>borazione vettoriale.<br />

VANTAGGI<br />

Dato che un’unica operazione vettoriale opera su più dati contemporaneamente<br />

questo consente <strong>di</strong> <strong>legge</strong>re meno dati rispetto a un c<strong>la</strong>ssico processore. I dati<br />

vettoriali sono tra <strong>di</strong> loro in<strong>di</strong>pendenti e quin<strong>di</strong> si può realizzare unità con un<br />

elevato parallelismo con unità <strong>di</strong> controllo più semplici e quin<strong>di</strong> con pochi<br />

transistor. Un numero ridotto <strong>di</strong> transistor consente <strong>di</strong> ottenere frequenze <strong>di</strong><br />

funzionamento elevate. Essendo il compi<strong>la</strong>tore che provvede a ridurre le<br />

<strong>di</strong>pendenze le unità <strong>di</strong> gestione <strong>di</strong>ventano ancora più semplici. Le istruzioni<br />

vettoriali accedono al<strong>la</strong> memoria secondo schemi noti quin<strong>di</strong> si possono<br />

ottimizzare gli accessi dato che i dati vengono salvati in ampi registri vettoriali.<br />

Inoltre queste unità possono fare a meno <strong>di</strong> cache dati.<br />

ARCHITETTURA<br />

Internamente un processore vettoriale è formato da un’architettura basata su<br />

registri vettoriali. Ogni registro vettoriale è composto da un insieme <strong>di</strong> registri<br />

caratterizzati da un unico nome e un in<strong>di</strong>ce che permette <strong>di</strong> accedere al singolo


100 Capitolo 3<br />

dato. Le operazioni vettoriali <strong>la</strong>vorano unicamente tra registri vettoriali tranne<br />

ovviamente le operazioni <strong>di</strong> load e <strong>di</strong> store che provvedono a caricare e<br />

scaricare i dati dai registri verso <strong>la</strong> memoria.<br />

I componenti <strong>di</strong> un processore vettoriale sono:<br />

• CPU sca<strong>la</strong>re: Questa unità è composta da registri, logica per <strong>la</strong> lettura<br />

delle istruzioni e del<strong>la</strong> loro deco<strong>di</strong>fica.<br />

• Registri vettoriali: Questi registri sono formati da un insieme <strong>di</strong> registri<br />

accorpati per nome e in<strong>di</strong>rizzabili tramite un in<strong>di</strong>ce. Sono dotati <strong>di</strong><br />

almeno due porte <strong>di</strong> lettura e <strong>di</strong> una <strong>di</strong> scrittura e possono essere da 8<br />

fino a 32. A volte i registri supportano parole <strong>di</strong> lunghezza variabile<br />

(8,16,32,64 bit) questo risulta comodo per applicazioni multime<strong>di</strong>ali.<br />

• Unità funzionale vettoriale: Questa unità è <strong>di</strong> tipo pipeline per poter<br />

iniziare una nuova operazione ogni ciclo <strong>di</strong> clock. Tipicamente ne<br />

esistono da 2 a 8 in grado <strong>di</strong> <strong>la</strong>vorare su interi o su numeri in virgo<strong>la</strong><br />

mobile.<br />

• Unità vettoriale <strong>di</strong> load-store: Questa unità è un’unità pipeline che<br />

provvede a <strong>legge</strong>re e scrivere i dati dai registri al<strong>la</strong> memoria. L’unità<br />

può <strong>legge</strong>re o scrivere più dati in contemporanea e in un processore<br />

possono esserci più unità <strong>di</strong> load-store.<br />

• Matrice <strong>di</strong> commutazione: Questa matrice mette in comunicazione le<br />

varie unità funzionali del processore.


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 101<br />

METODI DI ACCESSO<br />

Figura 3.18 – Schema a blocchi <strong>di</strong> una architettura vettoriale<br />

L’unità vettoriale <strong>di</strong> load-store usualmente supporta almeno tre modalità <strong>di</strong><br />

accesso.<br />

• Metodo <strong>di</strong> accesso a passo unitario, il più veloce.<br />

• Metodo <strong>di</strong> accesso a passo costante<br />

• Metodo <strong>di</strong> accesso in<strong>di</strong>cizzato. Accede al<strong>la</strong> memoria tramite un in<strong>di</strong>ce,<br />

SVANTAGGI<br />

è molto utile per accedere alle matrici sparse e permettere <strong>di</strong><br />

vettorializzare molti programmi<br />

Questi <strong>processori</strong> sono poco adatti all’e<strong>la</strong>borazione <strong>di</strong> dati <strong>di</strong>stribuiti in modo<br />

non costante e quin<strong>di</strong> le loro reali prestazioni <strong>di</strong>pendono dal<strong>la</strong> tipologia <strong>di</strong><br />

programma in esecuzione e in alcuni casi anche dai dati trattati.


102 Capitolo 3<br />

UNITÀ VETTORIALI<br />

Tutti i <strong>processori</strong> moderni supportano operazioni vettoriali. Questo perché i<br />

<strong>processori</strong> c<strong>la</strong>ssici mal si prestano all’e<strong>la</strong>borazione <strong>di</strong> dati multime<strong>di</strong>ali.<br />

L’utilizzo <strong>di</strong> chip de<strong>di</strong>cati per l’e<strong>la</strong>borazione multime<strong>di</strong>ali non ha mai preso<br />

piede dato che quieti chip sono limitati nell’utilizzo, complicano lo sviluppo <strong>dei</strong><br />

computer e non sono mai stati ben supportati dal software. Invece l’inclusione<br />

<strong>di</strong> queste unità nei <strong>processori</strong> moderni permette <strong>di</strong> migliorare le prestazione nel<br />

campo del multime<strong>di</strong>a senza incrementare i costi in modo significativo. Difatti<br />

basta aggiungere qualche registro (o utilizzarne alcuni poco usati come quelli<br />

del processore matematico), mo<strong>di</strong>ficare le pipeline in modo da poter gestire<br />

gruppi <strong>di</strong> dati in parallelo e aggiungere <strong>la</strong> deco<strong>di</strong>fica <strong>di</strong> alcune istruzioni in più.<br />

3.2.5 Limiti sul livello <strong>di</strong> parallelismo<br />

Il massimo numero <strong>di</strong> istruzioni eseguibili in parallelo viene limitato da tre<br />

problemi (in inglese definiti alee); il numero <strong>di</strong> unità funzionali, le <strong>di</strong>pendenze<br />

sui dati e le <strong>di</strong>pendenze sul controllo. Nello specifico:<br />

• Alee Strutturali: Banalmente se il processore è dotato <strong>di</strong> quattro unità <strong>di</strong><br />

calcolo questo non potrà eseguire più <strong>di</strong> quattro istruzioni in parallelo<br />

anche se nel co<strong>di</strong>ce fossero presenti più istruzioni eseguibili in<br />

parallelo.<br />

• Alee sui dati: Il processore non può eseguire (o completare)<br />

un’istruzione se non ha tutti i dati, se alcuni dati devono essere ancora<br />

e<strong>la</strong>borati (come nell’esempio con l’istruzione 3) il processore non può


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 103<br />

mandare in esecuzione (o completare, <strong>di</strong>pende da come è costruita<br />

l’unità funzionale) l’istruzione.<br />

• Alee <strong>di</strong> controllo: Il co<strong>di</strong>ce che si trova dopo un salto con<strong>di</strong>zionato non<br />

3.3 Cache<br />

può essere eseguito se prima non si stabilisce il risultato del salto<br />

con<strong>di</strong>zionato.<br />

La memoria principale costituita da RAM <strong>di</strong>namica (DRAM) è molto più lenta<br />

del<strong>la</strong> CPU e pertanto <strong>la</strong> necessità <strong>di</strong> <strong>legge</strong>re istruzioni e operan<strong>di</strong> dal<strong>la</strong> memoria<br />

causa un rallentamento rispetto alle prestazioni teoriche del<strong>la</strong> CPU. Il<br />

meccanismo <strong>di</strong> pipeline può in alcuni casi <strong>di</strong>minuire l’impatto <strong>di</strong> questo<br />

problema, eseguendo altre operazioni durante l’attesa.<br />

Il tempo impiegato per <strong>legge</strong>re un dato dal<strong>la</strong> memoria (<strong>la</strong> <strong>la</strong>tenza <strong>di</strong> lettura),<br />

però potrebbe essere tale per cui <strong>la</strong> CPU potrebbe completare <strong>la</strong> propria coda <strong>di</strong><br />

operazioni mentre aspetta l’arrivo del dato richiesto, generando uno stallo del<strong>la</strong><br />

CPU. Con l’aumento del<strong>la</strong> velocità <strong>dei</strong> micro<strong>processori</strong>, l’andare in stallo<br />

spreca molta potenza <strong>di</strong> calcolo; le CPU moderne, infatti, possono eseguire<br />

centinaia <strong>di</strong> istruzioni nello stesso tempo necessario per caricare un singolo dato<br />

dal<strong>la</strong> memoria.<br />

Nei paragrafi precedenti abbiamo illustrato alcune tecniche per "tenere<br />

occupata" <strong>la</strong> CPU durante questa fase, come l’esecuzione fuori or<strong>di</strong>ne e il<br />

multithrea<strong>di</strong>ng simultaneo, che permette ad un altro programma <strong>di</strong> usare <strong>la</strong> CPU


104 Capitolo 3<br />

mentre un primo programma sta aspettando l’arrivo <strong>di</strong> dati dal<strong>la</strong> memoria<br />

principale.<br />

Purtroppo il <strong>di</strong>vario <strong>di</strong> prestazioni tra memorie e CPU non tende a <strong>di</strong>minuire,<br />

ma al contrario <strong>di</strong>viene più marcato <strong>di</strong> anno in anno (ve<strong>di</strong> Figura 3.13): le<br />

memorie sembrano rallentare costantemente rispetto alle CPU e risulta sempre<br />

più <strong>di</strong>fficile costruire memorie in grado <strong>di</strong> fornire operan<strong>di</strong> in uno o due cicli <strong>di</strong><br />

clock. Uno <strong>dei</strong> mo<strong>di</strong> per far fronte a questo problema potrebbe essere quello <strong>di</strong><br />

utilizzare SRAM invece <strong>di</strong> DRAM: le SRAM sono molto più veloci, ma ahimè,<br />

anche molto più costose. Proprio per motivi <strong>di</strong> costo, non potendo realizzare<br />

con SRAM tutta <strong>la</strong> memoria principale, viene introdotto il meccanismo del<strong>la</strong><br />

cache, ovvero <strong>di</strong> una memoria veloce, <strong>di</strong> <strong>di</strong>mensione limitata rispetto all’intera<br />

RAM, da “interporre” tra CPU e RAM.<br />

Il principio <strong>di</strong> funzionamento è semplice. La CPU reperisce sempre i dati dal<strong>la</strong><br />

memoria cache, come se questa potesse contenere tutta l’informazione<br />

memorizzabile in RAM:<br />

• qualora <strong>la</strong> paro<strong>la</strong> desiderata sia effettivamente presente in cache (cache<br />

hit) otteniamo un in<strong>di</strong>scutibile vantaggio nel tempo <strong>di</strong> accesso.<br />

• d’altro canto se <strong>la</strong> paro<strong>la</strong> non è presente (cache miss), è necessario<br />

trasferir<strong>la</strong> da DRAM a cache e poi <strong>legge</strong>r<strong>la</strong>; in questo caso il tempo<br />

totale è sostanzialmente maggiore rispetto al<strong>la</strong> lettura da DRAM.<br />

Pertanto l’utilizzo <strong>di</strong> cache è vantaggioso solo quando <strong>la</strong> percentuale <strong>di</strong> hit è<br />

sufficientemente alta.


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 105<br />

Questa con<strong>di</strong>zione fondamentale è effettivamente verificata grazie a due<br />

principi, detti <strong>di</strong> Località Temporale e Località Spaziale.<br />

Grazie al<strong>la</strong> località temporale è assai probabile che una CPU debba accedere più<br />

<strong>di</strong> una volta ad uno stesso dato. Ovvero, dopo aver acceduto al tempo t ad un<br />

dato al<strong>la</strong> locazione addr, è assai probabile che ad un tempo ravvicinato t+dt si<br />

debba accedere al<strong>la</strong> stessa locazione.<br />

Il principio <strong>di</strong> località spaziale, invece, afferma che, dopo aver acceduto al<strong>la</strong><br />

locazione addr, in un tempo ravvicinato <strong>la</strong> CPU dovrà accedere con alta<br />

probabilità alle locazioni contigue ad addr.<br />

L’organizzazione delle memorie cache è tale da sfruttare questi due principi e<br />

rendere quin<strong>di</strong> altamente probabili i casi <strong>di</strong> hit rispetto a quelli <strong>di</strong> miss. Il fatto<br />

<strong>di</strong> trasferire un dato in cache a seguito <strong>di</strong> una miss, infatti, ha senso so<strong>la</strong>mente<br />

perché è assai probabile doverlo riusare.<br />

Inoltre, le politiche <strong>di</strong> allocazione <strong>di</strong> cache tengono conto del<strong>la</strong> località spaziale<br />

<strong>legge</strong>ndo normalmente più dati <strong>di</strong> quelli necessari (un intero blocco), con <strong>la</strong><br />

speranza che questi vengano in seguito richiesti; infine tengono conto del<strong>la</strong><br />

località temporale per decidere quale blocco <strong>di</strong> cache rimpiazzare (cioè quale<br />

blocco debba essere sovrascritto dal nuovo blocco entrante).<br />

Le prestazioni ottenute utilizzando le memorie cache risultano quin<strong>di</strong> molto<br />

migliori dell’uso del<strong>la</strong> so<strong>la</strong> memoria RAM.<br />

Il termine Cache deriva dal termine francese “caché” che significa “nascosto”,<br />

ed in<strong>di</strong>ca che il funzionamento <strong>di</strong> questa memoria è per scelta completamente<br />

trasparente (nascosto) al programmatore e gestito completamente in hardware.


106 Capitolo 3<br />

L’origine del nome ci sottolinea pertanto come i dati siano memorizzati in una<br />

posizione temporanea, dal<strong>la</strong> quale possono essere recuperati velocemente su<br />

richiesta.<br />

Le parole chiave sono “temporanea” e “velocemente”: in pratica, questo<br />

significa che non c’è nessuna certezza che i dati si trovino nel<strong>la</strong> cache, ma che<br />

convenga comunque fare un tentativo per verificarne l’eventuale esistenza.<br />

Il meccanismo <strong>di</strong> caching è utilizzato a <strong>di</strong>versi livelli; in questa trattazione<br />

parleremo esclusivamente <strong>di</strong> CPU cache, ovvero del<strong>la</strong> cache utilizzata dal<strong>la</strong><br />

CPU <strong>di</strong> un computer per ridurre il tempo me<strong>di</strong>o d’accesso al<strong>la</strong> memoria.<br />

3.3.1 Politiche <strong>di</strong> rimpiazzamento<br />

Come già detto, le memorie cache sono molto più piccole rispetto al<strong>la</strong> memoria<br />

principale e quin<strong>di</strong> è in<strong>di</strong>spensabile definire una politica <strong>di</strong> rimpiazzamento <strong>dei</strong><br />

blocchi. Per poter fare spazio a nuovi dati nel caso <strong>di</strong> un cache miss, <strong>la</strong> cache<br />

generalmente deve eliminare il contenuto <strong>di</strong> una delle linee. L’euristica che<br />

utilizza per scegliere quale dato eliminare è chiamata politica <strong>di</strong><br />

rimpiazzamento. Il problema fondamentale <strong>di</strong> ogni politica <strong>di</strong> rimpiazzamento è<br />

quello <strong>di</strong> dover pre<strong>di</strong>re il dato del<strong>la</strong> cache che verrà richiesto nel futuro con<br />

minor probabilità. Pre<strong>di</strong>re il futuro è <strong>di</strong>fficile, soprattutto per le cache hardware<br />

che devono sfruttare regole facilmente implementabili in circuiteria, perciò<br />

esistono una serie <strong>di</strong> politiche <strong>di</strong> rimpiazzamento e nessuna <strong>di</strong> esse può essere<br />

ritenuta perfetta. Una delle più popo<strong>la</strong>ri, <strong>la</strong> LRU (dall’inglese Least Recently


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 107<br />

Used, cioè usato meno recentemente), rimpiazza, appunto, il dato al quale si è<br />

fatto accesso meno recentemente.<br />

3.3.2 Politiche <strong>di</strong> salvataggio<br />

Quando un dato è scritto nel<strong>la</strong> cache, dopo un po’ <strong>di</strong> tempo deve comunque<br />

essere scritto in memoria principale. La decisione del momento in cui questa<br />

scrittura deve aver luogo è control<strong>la</strong>ta dal<strong>la</strong> politica <strong>di</strong> scrittura. In una cache<br />

“write-through”, ogni scrittura sul<strong>la</strong> cache comporta una scrittura<br />

contemporanea nel<strong>la</strong> memoria principale. In alternativa, una cache “write-<br />

back” non esegue imme<strong>di</strong>atamente questa azione: al contrario, <strong>la</strong> cache tiene<br />

traccia delle linee che contengono dati da aggiornare settando opportunamente<br />

quello che viene chiamato il <strong>di</strong>rty bit. Il dato viene effettivamente scritto in<br />

memoria solo quando esso deve essere eliminato dal<strong>la</strong> cache per far spazio a<br />

nuove informazioni. Per questa ragione, una ricerca fallita in una cache write-<br />

back spesso genera due accessi al<strong>la</strong> memoria: uno per <strong>legge</strong>re il nuovo dato,<br />

l’altro per scrivere <strong>la</strong> vecchia informazione (se in<strong>di</strong>cato dal <strong>di</strong>rty bit).<br />

Esistono anche alcune politiche interme<strong>di</strong>e. La cache potrebbe essere ad<br />

esempio write-through, ma le scritture potrebbero essere temporaneamente<br />

inserite in una coda, così da processare insieme scritture multiple, ottimizzando<br />

l’accesso al bus.


108 Capitolo 3<br />

3.3.3 Protocolli <strong>di</strong> coerenza<br />

I dati in memoria principale, <strong>dei</strong> quali esiste una copia nel<strong>la</strong> cache, potrebbero<br />

essere mo<strong>di</strong>ficati da altre cause (evento non improbabile, ad esempio, in un<br />

sistema multiprocessore), perciò i dati nel<strong>la</strong> cache potrebbero <strong>di</strong>ventare obsoleti.<br />

I protocolli <strong>di</strong> comunicazione tra i sistemi <strong>di</strong> gestione delle cache che<br />

conservano <strong>la</strong> consistenza <strong>dei</strong> dati sono chiamati protocolli <strong>di</strong> coerenza.<br />

3.3.4 Associatività<br />

La politica <strong>di</strong> rimpiazzamento decide dove, nel<strong>la</strong> cache, può risiedere una copia<br />

<strong>di</strong> una partico<strong>la</strong>re locazione <strong>di</strong> memoria. Se <strong>la</strong> politica <strong>di</strong> rimpiazzamento è<br />

libera <strong>di</strong> scegliere in quale linea <strong>di</strong> cache caricare il dato, <strong>la</strong> cache è chiamata<br />

“fully associative” (o anche completamente associativa). Invece, se ogni dato in<br />

memoria può essere posizionato solo in una partico<strong>la</strong>re linea <strong>di</strong> cache, essa è<br />

detta “<strong>di</strong>rect mapped” (o anche a mappatura <strong>di</strong>retta). La maggior parte delle<br />

cache, però, implementa un compromesso chiamato “set associative” (o anche<br />

parzialmente associativa). Per esempio, <strong>la</strong> cache dati <strong>di</strong> livello 1 dell’AMD ®<br />

Athlon è 2-way set associative, cioè una partico<strong>la</strong>re locazione <strong>di</strong> memoria può<br />

essere caricata in cache in due <strong>di</strong>stinte locazioni nel<strong>la</strong> cache dati <strong>di</strong> livello 1.<br />

Se ogni locazione in memoria principale può essere caricata in due locazioni<br />

<strong>di</strong>verse, <strong>la</strong> domanda sorge spontanea: quali? Lo schema utilizzato più<br />

frequentemente è mostrato nel<strong>la</strong> Figura 3.19: i bit meno significativi dell’in<strong>di</strong>ce<br />

del<strong>la</strong> locazione <strong>di</strong> memoria vengono usati come in<strong>di</strong>ci per <strong>la</strong> cache e ad ognuno


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 109<br />

<strong>di</strong> questi in<strong>di</strong>ci sono associate due linee <strong>di</strong> cache. Una buona proprietà <strong>di</strong> questo<br />

schema è che le etichette <strong>dei</strong> dati caricati in cache non devono includere quel<strong>la</strong><br />

parte dell’in<strong>di</strong>ce già co<strong>di</strong>ficata dal<strong>la</strong> linea <strong>di</strong> cache scelta. Poiché i tag sono<br />

espressi su meno bit, occupano meno memoria ed il tempo per processarli è<br />

minore.<br />

Figura 3.19 –Modalità <strong>di</strong> riempimento del<strong>la</strong> cache nel caso <strong>di</strong> memoria cache<br />

“Mappata Direttamente” e “Associativa a 2 vie”<br />

Sono stati suggeriti altri schemi, come quello del<strong>la</strong> “skewed cache”, dove<br />

l’in<strong>di</strong>ce del<strong>la</strong> way 0 è <strong>di</strong>retto, come sopra, mentre l’in<strong>di</strong>ce per <strong>la</strong> way 1 è<br />

calco<strong>la</strong>to attraverso una funzione <strong>di</strong> hash. Una buona funzione <strong>di</strong> hash ha <strong>la</strong><br />

proprietà che gli in<strong>di</strong>rizzi che sono in conflitto con il <strong>di</strong>rect mapping tendono a<br />

non collidere quando sono mappati con <strong>la</strong> funzione <strong>di</strong> hash, così è meno<br />

probabile che un programma soffra <strong>di</strong> un numero impreve<strong>di</strong>bilmente grande <strong>di</strong><br />

collisioni dovuti ad un metodo d’accesso partico<strong>la</strong>rmente patologico. Lo<br />

svantaggio è il ritardo aggiuntivo necessario per calco<strong>la</strong>re il risultato del<strong>la</strong><br />

funzione <strong>di</strong> hash. In aggiunta, quando <strong>di</strong>venta necessario caricare una nuova


110 Capitolo 3<br />

linea ed eliminarne una vecchia, potrebbe rive<strong>la</strong>rsi <strong>di</strong>fficile determinare quale<br />

tra le linee esistenti è stata usata meno recentemente, in quanto <strong>la</strong> nuova linea<br />

entra in conflitto con <strong>di</strong>fferenti "set" <strong>di</strong> linee per ogni "way"; il tracciamento<br />

LRU è infatti normalmente calco<strong>la</strong>to per ogni set <strong>di</strong> linee.<br />

L’associatività è un compromesso. Se ci sono <strong>di</strong>eci posizioni, <strong>la</strong> politica <strong>di</strong><br />

rimpiazzamento può riempire una nuova linea, ma quando bisogna cercare un<br />

dato devono essere control<strong>la</strong>te tutte e 10 le posizioni. Control<strong>la</strong>re più posizioni<br />

necessita <strong>di</strong> più potenza, area e tempo. D’altra parte, le cache con più<br />

associatività soffrono <strong>di</strong> meno cache miss. La rego<strong>la</strong> <strong>di</strong> massima è che<br />

raddoppiare l’associatività ha circa lo stesso effetto sull’hit rate che il raddoppio<br />

del<strong>la</strong> <strong>di</strong>mensione del<strong>la</strong> cache, da 1-way (<strong>di</strong>rect mapping) a 4-way. Aumenti<br />

dell’associatività oltre il 4-way hanno molto meno effetto sull’hit rate e sono<br />

generalmente utilizzati per altri motivi (come ad esempio il virtual aliasing).<br />

Uno <strong>dei</strong> vantaggi del<strong>la</strong> cache <strong>di</strong>rect mapped è che permette una esecuzione<br />

specu<strong>la</strong>tiva semplice e veloce. Una volta che l’in<strong>di</strong>rizzo è stato calco<strong>la</strong>to, è nota<br />

quale sia <strong>la</strong> linea <strong>di</strong> cache che potrebbe contenere il dato. Questa può essere<br />

letta ed il processore può continuare a <strong>la</strong>vorare con quel dato prima che finisca<br />

<strong>di</strong> control<strong>la</strong>re che l’etichetta effettivamente combaci con l’in<strong>di</strong>rizzo richiesto.<br />

L’idea che il processore utilizzi i dati in cache prima ancora che sia verificata <strong>la</strong><br />

corrispondenza tra etichetta ed in<strong>di</strong>rizzo può essere applicata anche alle cache<br />

associative. Un sottoinsieme dell’etichetta, chiamato in inglese hint, può essere


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 111<br />

utilizzato per scegliere temporaneamente una delle linee <strong>di</strong> cache associate<br />

all’in<strong>di</strong>rizzo richiesto. Questo dato può essere utilizzato dal<strong>la</strong> CPU in parallelo,<br />

mentre l’etichetta viene control<strong>la</strong>ta completamente. Questa tecnica <strong>la</strong>vora al<br />

meglio quando usata nel contesto del<strong>la</strong> traduzione degli in<strong>di</strong>rizzi, come spiegato<br />

più in basso<br />

3.3.5 Obiettivo: Minimizzare i Cache miss<br />

Con il termine “cache miss” (ovvero fallimento del<strong>la</strong> cache) ci si riferisce ad un<br />

intento fallito nel <strong>legge</strong>re o scrivere un pezzo <strong>di</strong> dati nel<strong>la</strong> cache, che ha come<br />

risultato una <strong>la</strong>tenza molto più lunga nell’accesso al<strong>la</strong> memoria principale.<br />

Quando si verifica un fallimento nel<strong>la</strong> lettura dal<strong>la</strong> cache istruzioni, il<br />

processore deve aspettare (si genera cioè uno stallo) finché l’istruzione non è<br />

caricata dal<strong>la</strong> memoria principale. Un fallimento del<strong>la</strong> cache causato dal<br />

caricamento <strong>di</strong> un dato può invece essere meno doloroso, perché le altre<br />

istruzioni non corre<strong>la</strong>te ad esso possono comunque essere eseguite, finché<br />

l’operazione che richiede i dati da caricare può essere eseguita. Comunque, i<br />

dati sono spesso usati imme<strong>di</strong>atamente dopo l’istruzione <strong>di</strong> caricamento.<br />

L’ultimo caso <strong>di</strong> cache miss, cioè un fallimento in scrittura, è il meno<br />

preoccupante, perché <strong>di</strong> solito <strong>la</strong> scrittura è bufferizzata. Il processore può<br />

continuare tranquil<strong>la</strong>mente finché il buffer non è pieno. (Non esiste un<br />

fallimento nel<strong>la</strong> scrittura del<strong>la</strong> cache istruzioni perché esse sono <strong>di</strong> so<strong>la</strong> lettura.)


112 Capitolo 3<br />

Per minimizzare <strong>la</strong> frequenza <strong>di</strong> cache miss, un grande sforzo <strong>di</strong> analisi è stato<br />

fatto sul comportamento del<strong>la</strong> cache per trovare <strong>la</strong> miglior combinazione <strong>di</strong><br />

<strong>di</strong>mensione, associatività, <strong>di</strong>mensione <strong>dei</strong> blocchi e così via. Sequenze <strong>di</strong><br />

referenze <strong>di</strong> memoria create dai programmi <strong>di</strong> benchmark sono salvati come<br />

“address traces”. Ulteriori analisi simu<strong>la</strong>no molte <strong>di</strong>fferenti possibilità <strong>di</strong><br />

implementazione del<strong>la</strong> cache basate su queste lunghe address traces. Far capire<br />

come le molteplici variabili mo<strong>di</strong>fichino <strong>la</strong> frequenza <strong>di</strong> cache hit può risultare<br />

abbastanza confusionario. Un contributo significante fu fatto da Mark Hill, il<br />

quale separò i vari fallimenti del<strong>la</strong> cache in tre categorie (conosciute come "le<br />

tre C") [13]:<br />

• Compulsory misses sono quei fallimenti causati dal<strong>la</strong> prima referenza<br />

ad un dato. La <strong>di</strong>mensione del<strong>la</strong> cache e <strong>la</strong> associatività non fanno<br />

<strong>di</strong>fferenze al numero <strong>di</strong> compulsory misses. Il prefetching può aiutare<br />

qui, così come lo possono fare <strong>la</strong>rghe <strong>di</strong>mensioni <strong>dei</strong> blocchi del<strong>la</strong><br />

cache (che sono un tipo <strong>di</strong> prefetching).<br />

• Capacity misses sono quei fallimenti che una cache <strong>di</strong> una data<br />

<strong>di</strong>mensione avrà, a <strong>di</strong>spetto dell’associatività o del<strong>la</strong> <strong>di</strong>mensione del<br />

blocco. La curva del<strong>la</strong> frequenza <strong>dei</strong> capacity misses rispetto al<strong>la</strong><br />

<strong>di</strong>mensione del<strong>la</strong> cache fornisce una qualche misura del<strong>la</strong> località<br />

temporanea <strong>di</strong> un partico<strong>la</strong>re flusso <strong>di</strong> referenze.<br />

• Conflict misses sono quei fallimenti che si sarebbero potuti evitare, se <strong>la</strong><br />

cache non avesse ripulito un dato precedentemente. I conflict misses<br />

potrebbero essere ulteriormente <strong>di</strong>visi in mapping misses, che sono


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 113<br />

inevitabili data una partico<strong>la</strong>re associatività, e rep<strong>la</strong>cement misses, che<br />

sono causati dal<strong>la</strong> partico<strong>la</strong>re scelta del<strong>la</strong> rego<strong>la</strong> <strong>di</strong> rimpiazzamento.<br />

Figura 3.20 - Frequenza <strong>di</strong> fallimento (miss rate) a confronto con <strong>la</strong> <strong>di</strong>mensione del<strong>la</strong><br />

cache (Cache size) sul<strong>la</strong> porzione degli interi <strong>di</strong> SPEC CPU2000<br />

Il grafico in figura riassume <strong>la</strong> performance del<strong>la</strong> cache vista dai benchmarks<br />

del<strong>la</strong> porzione degli interi <strong>di</strong> un SPEC CPU2000, ripresa da Hill e Cantin.<br />

Questi benchmark servono a rappresentare il tipo <strong>di</strong> carico <strong>di</strong> <strong>la</strong>voro che una<br />

postazione <strong>di</strong> <strong>la</strong>voro potrebbe subire un giorno qualsiasi. In questo grafico<br />

possiamo vedere i <strong>di</strong>fferenti effetti delle tre C.<br />

All’estrema destra, quando <strong>la</strong> cache size assume un valore "Inf" (che, in altre<br />

parole, tende all’infinito), abbiamo i compulsory misses. Se volessimo<br />

migliorare le caratteristiche dello SpecInt2000, aumentare <strong>la</strong> <strong>di</strong>mensione del<strong>la</strong><br />

cache oltre 1MB sarebbe praticamente inutile.


114 Capitolo 3<br />

La frequenza <strong>di</strong> fallimento del<strong>la</strong> cache fully-associative rappresenta a pieno <strong>la</strong><br />

frequenza <strong>dei</strong> capacity misses. Nelle simu<strong>la</strong>zioni, è stata scelta una rego<strong>la</strong> <strong>di</strong><br />

rimpiazzamento LRU: questo mostra che per minimizzare <strong>la</strong> frequenza <strong>dei</strong><br />

capacity misses sarebbe necessaria una rego<strong>la</strong> <strong>di</strong> rimpiazzamento perfetta, come<br />

se ad esempio un veggente indagasse nel futuro per trovare una posizione del<strong>la</strong><br />

cache che non stia per essere utilizzata.<br />

È da notare come, nel<strong>la</strong> nostra approssimazione del<strong>la</strong> frequenza <strong>dei</strong> capacity<br />

misses, il grafico abbia una brusca caduta tra i 32KB e i 64KB. Questo in<strong>di</strong>ca<br />

che il benchmark ha un settaggio <strong>di</strong> <strong>la</strong>vorazione <strong>di</strong> circa 64KB. Un progettista<br />

<strong>di</strong> cache, esaminando questi benchmark, sarebbe fortemente tentato <strong>di</strong> settare <strong>la</strong><br />

<strong>di</strong>mensione del<strong>la</strong> cache appena sopra i 64KB, piuttosto che appena sotto questo<br />

valore. Bisogna notare inoltre che, su questa simu<strong>la</strong>zione, nessun tipo <strong>di</strong><br />

associatività può far andare una cache a 32KB bene come una da 64KB 4-way,<br />

o ad<strong>di</strong>rittura come una <strong>di</strong>rect-mapped da 128KB.<br />

Infine, tra i 64KB ed 1MB c’è una grande <strong>di</strong>fferenza tra <strong>la</strong> cache <strong>di</strong> tipo <strong>di</strong>rect-<br />

mapped e quel<strong>la</strong> fully-associative. Questa <strong>di</strong>fferenza è <strong>la</strong> frequenza <strong>dei</strong> conflict<br />

misses. Secondo i dati del 2004, le cache <strong>di</strong> secondo livello montate<br />

<strong>di</strong>rettamente sul chip del processore tendono a stare in questo intervallo <strong>di</strong><br />

valori, in quanto le cache piccole sono abbastanza veloci da essere cache <strong>di</strong><br />

primo livello, mentre quelle più gran<strong>di</strong> sono troppo costose per essere montate<br />

economicamente sul chip stesso (l’Itanium 2 ha una cache <strong>di</strong> terzo livello da


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 115<br />

9MB, <strong>la</strong> più grande cache on-chip <strong>di</strong>sponibile sul mercato nel 2004). Dal punto<br />

<strong>di</strong> vista del<strong>la</strong> frequenza <strong>dei</strong> conflict misses, risulta che <strong>la</strong> cache <strong>di</strong> secondo<br />

livello trae un grande beneficio dall’alta associatività.<br />

Questo beneficio era ben conosciuto nei tar<strong>di</strong> anni 80 e primi anni 90, quando i<br />

progettisti <strong>di</strong> CPU non potevano far stare gran<strong>di</strong> cache sui chip e non<br />

<strong>di</strong>sponevano <strong>di</strong> sufficiente <strong>la</strong>rghezza <strong>di</strong> banda per implementare alta<br />

associatività sulle cache al <strong>di</strong> fuori del chip del processore. Furono provate varie<br />

soluzioni: il MIPS R8000 usava delle costose SRAM off-chip de<strong>di</strong>cate, che<br />

includevano <strong>dei</strong> comparatori <strong>di</strong> etichette e <strong>dei</strong> gran<strong>di</strong> driver, per implementare<br />

una cache associativa 4-way da 4MB. Il MIPS R10000 usava <strong>dei</strong> chip or<strong>di</strong>nari<br />

<strong>di</strong> SRAM per le etichette. L’accesso alle etichette, in entrambe le <strong>di</strong>rezioni,<br />

necessitava <strong>di</strong> due cicli: per ridurre <strong>la</strong> <strong>la</strong>tenza, il R10000, per ogni accesso,<br />

cercava <strong>di</strong> pre<strong>di</strong>re quale modo del<strong>la</strong> cache sarebbe stato quello corretto.<br />

3.3.6 Gerarchie delle cache<br />

Nei calco<strong>la</strong>tori moderni vengono spesso utilizzate più cache. Innanzitutto le<br />

cache sono oggigiorno <strong>di</strong>fferenziate in cache dati e cache istruzioni. Infatti per i<br />

due gruppi <strong>di</strong> informazioni le località e le politiche sono <strong>di</strong>verse. Inoltre è<br />

possibile aumentare il parallelismo evitando conflitti tra le fasi <strong>di</strong> fetch e <strong>di</strong><br />

trasferimento degli operan<strong>di</strong>.<br />

Inoltre si usano <strong>di</strong>versi livelli <strong>di</strong> cache (L1, L2, ...) in cascata per ottimizzare il<br />

trade-off costi/prestazioni. Si parte quin<strong>di</strong> da un primo livello molto veloce,


116 Capitolo 3<br />

normalmente integrato con <strong>la</strong> CPU, ma <strong>di</strong> <strong>di</strong>mensione limitata. Il secondo<br />

livello, più lento e <strong>di</strong>stante dal<strong>la</strong> CPU del primo, è invece più grande in termini<br />

<strong>di</strong> numero <strong>di</strong> locazioni, e così via. Di solito vengono utilizzati 2 soli livelli <strong>di</strong><br />

cache. Normalmente <strong>la</strong> cache <strong>di</strong> livello i+1-esimo mantiene l’intero contenuto<br />

<strong>di</strong> quel<strong>la</strong> <strong>di</strong> livello i-esimo. Analizziamo in dettagli questi due aspetti, chiamati<br />

rispettivamente “specializzazione delle cache” e “cache multilivello”.<br />

SPECIALIZZAZIONE DELLE CACHE<br />

Il primo motivo è che CPU con pipeline accedono al<strong>la</strong> memoria da molteplici<br />

punti nel<strong>la</strong> pipeline: recupero delle istruzioni, traduzione in<strong>di</strong>rizzi da virtuali a<br />

fisici, e recupero <strong>dei</strong> dati.<br />

La naturale implementazione è <strong>di</strong> utilizzare <strong>di</strong>fferenti cache fisiche per ognuno<br />

<strong>di</strong> questi punti, cosicché nessuna risorsa fisica debba essere programmata per<br />

servire due punti nel<strong>la</strong> pipeline. La pipeline verrà pertanto normalmente servita<br />

con almeno tre cache separate (istruzioni, TLB, e dati), ognuna specializzata in<br />

un ruolo partico<strong>la</strong>re.<br />

VICTIM CACHE<br />

Una “victim cache” è una cache utilizzata per mantenere blocchi rimossi dal<strong>la</strong><br />

cache del<strong>la</strong> CPU a causa <strong>di</strong> un conflict miss o capacity miss. La victim cache è<br />

situata tra <strong>la</strong> cache primaria e <strong>la</strong> memoria sottostante, e mantiene so<strong>la</strong>mente i<br />

blocchi rimossi dopo un miss. Questa tecnica è utilizzata per ridurre <strong>la</strong> penalità<br />

in cui si incorre per un fallimento del<strong>la</strong> cache.<br />

TRACE CACHE


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 117<br />

Uno <strong>dei</strong> più estremi esempi <strong>di</strong> specializzazione del<strong>la</strong> cache è quello del<strong>la</strong> trace<br />

cache utilizzata nei micro<strong>processori</strong> Pentium ® 4. Una trace cache è un<br />

meccanismo per aumentare il fetch bandwidth <strong>di</strong> istruzioni immagazzinando<br />

tracce <strong>di</strong> istruzioni che sono già state immagazzinate. Il meccanismo fu per <strong>la</strong><br />

prima volta proposto da Eric Rotenberg, Steve Bennett, e Jim Smith nel loro<br />

articolo del 1996: “Trace Cache: a Low Latency Approach to High Bandwidth<br />

Instruction Fetching”[14].<br />

Una trace cache immagazzina le istruzioni sia dopo che esse sono state<br />

deco<strong>di</strong>ficate, che quando sono ritirate. Generalmente, le istruzioni vengono<br />

aggiunte alle trace cache in gruppi che rappresentano sia blocchi in<strong>di</strong>viduali <strong>di</strong><br />

base che tracce <strong>di</strong>namica <strong>di</strong> istruzioni. Un blocco base consiste in un gruppo <strong>di</strong><br />

istruzioni non-branch (Non sud<strong>di</strong>vise) che finiscono con una ramificazione. Una<br />

traccia <strong>di</strong>namica ("trace path" o "traccia del percorso") consiste nelle sole<br />

istruzioni <strong>di</strong> cui il risultato viene effettivamente utilizzato, ed elimina le<br />

istruzioni seguenti che prendono ramificazioni (Siccome non sono eseguite);<br />

una traccia <strong>di</strong>namica può essere il concatenamento <strong>di</strong> più blocchi base. Questo<br />

permette all’unità <strong>di</strong> recupero delle istruzioni <strong>di</strong> recuperare parecchi blocchi <strong>di</strong><br />

base, senza <strong>la</strong> preoccupazioni riguardanti <strong>la</strong> ramificazione nel flusso <strong>di</strong><br />

esecuzione.<br />

Le linee <strong>di</strong> traccia vengono immagazzinate nel<strong>la</strong> trace cache in base al program<br />

counter del<strong>la</strong> prima istruzione nel<strong>la</strong> traccia e un set <strong>di</strong> pre<strong>di</strong>zioni <strong>di</strong>


118 Capitolo 3<br />

ramificazioni. Questo permette l’immagazzinamento <strong>di</strong> <strong>di</strong>fferenti tracce <strong>di</strong><br />

percorsi che iniziano con lo stesso in<strong>di</strong>rizzo, ognuna delle quali rappresenta<br />

<strong>di</strong>fferenti risultati <strong>di</strong> ramificazione. Nello stage dell’immagazzinamento delle<br />

istruzioni <strong>di</strong> una Instruction pipeline, il program counter corrente insieme ad un<br />

set <strong>di</strong> pre<strong>di</strong>zioni <strong>di</strong> ramificazione viene control<strong>la</strong>to nel<strong>la</strong> trace cache per un hit.<br />

Se un hit avviene, una linea <strong>di</strong> trace viene fornita per recuperare quale non deve<br />

andare in una cache rego<strong>la</strong>re o in memoria per queste istruzioni. <strong>la</strong> trace cache<br />

continua ad alimentare <strong>la</strong> fetch unit fino a che <strong>la</strong> trace line finisce o fino a che vi<br />

sia una mispre<strong>di</strong>ction nel<strong>la</strong> pipeline. Se c’è un fallimento, una nuova traccia<br />

inizia ad essere creata. Il vantaggio rispetto alle normali cache per il co<strong>di</strong>ce è<br />

che non vengono mantenute in cache tutte le istruzioni successive ad un branch<br />

che sia incon<strong>di</strong>zionato o predetto come non seguito: il risultato è che non si<br />

formano "bolle" <strong>di</strong> co<strong>di</strong>ce non utilizzato che sprecano spazio <strong>di</strong> memoria del<strong>la</strong><br />

cache.<br />

Le Trace cache vengono anche impiegate in <strong>processori</strong> quali l’ <strong>Intel</strong> ® Pentium ® 4<br />

per immagazzinare micro operazioni già deco<strong>di</strong>ficate, o traduzioni <strong>di</strong> complesse<br />

istruzioni x86, cosicché <strong>la</strong> prossima volta che una istruzione sia richiesta, non<br />

debba essere deco<strong>di</strong>ficata un’altra volta.<br />

L’idea che sta al<strong>la</strong> base del<strong>la</strong> trace cache è che nei <strong>processori</strong> CISC che<br />

internamente utilizzano istruzioni RISC, come il Pentium ® 4, <strong>la</strong> deco<strong>di</strong>fica delle<br />

istruzioni è una operazione estremamente onerosa, e il suo risultato dovrebbe


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 119<br />

essere sfruttato al meglio. Utilizzare una trace cache in luogo <strong>di</strong> una normale<br />

cache ha proprio questo vantaggio: non dover deco<strong>di</strong>ficare una istruzione già<br />

incontrata durante l’esecuzione <strong>di</strong> un programma.<br />

Ultimamente <strong>la</strong> trace cache non gode <strong>di</strong> molti favori a causa <strong>di</strong> alcuni <strong>di</strong>fetti. Il<br />

primo è che molte istruzioni RISC sono tradotte in una singo<strong>la</strong> istruzione CISC<br />

in un solo ciclo <strong>di</strong> clock, e le istruzioni che necessitano <strong>di</strong> più cicli <strong>di</strong> clock per<br />

essere tradotte in più istruzioni <strong>di</strong> tipo RISC sono re<strong>la</strong>tivamente poche e poco<br />

frequenti, per cui il vantaggio effettivo del<strong>la</strong> trace cache è limitato. A questo si<br />

aggiunge il fatto che, nel caso dell’architettura <strong>di</strong> <strong>Intel</strong> ® , le istruzioni <strong>di</strong> tipo<br />

CISC hanno lunghezza variabile in genere tra 1 e 6 byte (tra gli 8 e i 48 bit),<br />

mentre tutte le istruzioni RISC utilizzate internamente hanno lunghezza fissa <strong>di</strong><br />

118 bit. Quin<strong>di</strong> a parità <strong>di</strong> <strong>di</strong>mensioni una trace cache contiene molte meno<br />

istruzioni <strong>di</strong> una cache normale.<br />

CACHE MULTILIVELLO<br />

Il secondo motivo è il fondamentale compromesso tra <strong>la</strong> cache <strong>la</strong>tency ed l’hit<br />

rate. Le cache più gran<strong>di</strong> sono più lente e hanno migliori hit rate. Per migliorare<br />

questo tradeoff, molti sistemi utilizzano livelli multipli <strong>di</strong> cache, con cache<br />

piccole e veloci che si appoggiano a cache più gran<strong>di</strong> e più lente.


120 Capitolo 3<br />

Figura 3.21 - Un esempio <strong>di</strong> architettura con 3 livelli <strong>di</strong> cache. Le cache sono<br />

normalmente inclusive, ossia L1⊆ L2 ⊆ L3 [12]<br />

Siccome <strong>la</strong> <strong>di</strong>fferenza <strong>di</strong> <strong>la</strong>tenza tra <strong>la</strong> memoria principale e le cache più veloci<br />

è <strong>di</strong>ventata più grande, alcuni <strong>processori</strong> hanno cominciato ad utilizzare anche<br />

tre livelli <strong>di</strong> cache nel chip. Per esempio nel 2003, Itanium II iniziò ad essere<br />

fornito con una cache sul chip unificata <strong>di</strong> livello 3 <strong>di</strong> 6MB. L’IBM Power 4<br />

series ha una cache <strong>di</strong> livello 3 a 256MB fuori dal chip, con<strong>di</strong>visa tra parecchi<br />

<strong>processori</strong>.<br />

Le cache multilivello generalmente operano control<strong>la</strong>ndo dapprima le cache a<br />

livello 1; se avviene un hit, il processore procede ad alta velocità. Se <strong>la</strong> cache<br />

più picco<strong>la</strong> “fallisce”, allora viene control<strong>la</strong>ta quel<strong>la</strong> più grande e così via, fino<br />

ad dover accedere al<strong>la</strong> memoria principale.<br />

Le cache multi livello introducono un nuovo modello decisionale. Per esempio,<br />

in alcuni <strong>processori</strong> (come gli <strong>Intel</strong> ® Pentium ® 2, 3, e 4, così come in molti<br />

RISC), i dati nel<strong>la</strong> cache L1 possono essere anche in quel<strong>la</strong> L2. Queste cache


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 121<br />

vengono denominato inclusive. Altri <strong>processori</strong> (come l’AMD ® Athlon) hanno<br />

cache exclusive in cui è garantito che i dati siano al massimo in una delle cache<br />

L1 o L2.<br />

Il vantaggio delle cache exclusive è che memorizzano più dati. Questo<br />

vantaggio aumenta con cache più gran<strong>di</strong> (le implementazioni <strong>Intel</strong> ® x86 invece<br />

no). Un vantaggio delle cache inclusive è che quando devices esterni o altri<br />

<strong>processori</strong> in un sistema multiprocessore desiderano rimuovere una linea <strong>di</strong><br />

cache dal processore, devono far control<strong>la</strong>re al processore solo <strong>la</strong> cache L2.<br />

Nelle gerarchie <strong>di</strong> cache che non usano l’inclusione, le cache L1 devono essere<br />

control<strong>la</strong>te anch’esse. C’è una corre<strong>la</strong>zione tra <strong>la</strong> associatività delle cache L1 e<br />

L2: se le cache L2 non hanno almeno tanti mo<strong>di</strong> come tutte le L1 insieme,<br />

l’effettiva associatività delle cache L1 risulta confinata.<br />

Un altro vantaggio delle cache inclusive è che le cache più gran<strong>di</strong> possono usare<br />

linee <strong>di</strong> cache più gran<strong>di</strong>, che riducono <strong>la</strong> <strong>di</strong>mensione delle etichette delle cache<br />

secondarie. Se <strong>la</strong> cache secondaria è <strong>di</strong> un or<strong>di</strong>ne <strong>di</strong> grandezza maggiore <strong>di</strong><br />

quel<strong>la</strong> primaria, e i dati del<strong>la</strong> cache sono <strong>di</strong> un or<strong>di</strong>ne <strong>di</strong> grandezza più grande<br />

delle etichette del<strong>la</strong> cache, queste etichette <strong>di</strong> dati salvati può essere confrontato<br />

con l’area incrementale necessaria ad immagazzinare i dati nel<strong>la</strong> cache L1 ed<br />

L2.


122 Capitolo 3<br />

Come menzionato prima, gran<strong>di</strong> computer hanno a volte un’altra cache tra<br />

quel<strong>la</strong> L2 e <strong>la</strong> memoria principale chiamata cache L3. Questa cache è<br />

implementata generalmente su <strong>di</strong> un chip separato dal<strong>la</strong> CPU, e come nel 2004,<br />

ha un capacità dai 2MB ai 256MB. Queste cache costeranno ben oltre i $1000<br />

da costruire, ed i loro benefici <strong>di</strong>penderanno dai percorsi <strong>di</strong> accesso delle<br />

applicazioni. Workstation x86 <strong>di</strong> fascia alta e server sono ora <strong>di</strong>sponibili con<br />

un’opzione per <strong>la</strong> cache L3.<br />

Infine, dall’altro <strong>la</strong>to del<strong>la</strong> gerarchia del<strong>la</strong> memoria, Il Register file del<strong>la</strong> CPU<br />

può essere considerato <strong>la</strong> più picco<strong>la</strong>, veloce cache nel sistema, con <strong>la</strong> speciale<br />

caratteristica che viene richiamata dal software, tipicamente da un compi<strong>la</strong>tore,<br />

siccome alloca registri che devono mantenere valori recuperati dal<strong>la</strong> memoria<br />

principale.<br />

3.4 Set <strong>di</strong> Istruzioni<br />

Negli anni settanta si delineano in partico<strong>la</strong>re due filosofie <strong>di</strong> progettazione<br />

<strong>di</strong>fferenti inerenti il set <strong>di</strong> istruzioni: RISC (Reduced Instruction Set<br />

Computing) e CISC (Complex Instruction Set Computing).<br />

La Figura 3.22 mostra sinteticamente le <strong>di</strong>fferenze delle due filosofie così come<br />

si erano delineate negli anni ’70.


Mo<strong>di</strong>fiche <strong>architetturali</strong> per il miglioramento delle prestazioni 123<br />

Figura 3.22 – CISC vs RISC[15]<br />

A partire dall’inizio degli anni ‘90 si assiste invece una sostanziale mesco<strong>la</strong>nza<br />

delle caratteristiche delle due con maggiore attenzione al raggiungimento delle<br />

migliori prestazioni che ai ‘precetti’ che questi due acronimi sottendono.<br />

Naturalmente le <strong>di</strong>fferenze strutturali tra i due approcci permangono, una su<br />

tutte: il numero <strong>di</strong> registri in<strong>di</strong>rizzabili dai rispettivi set <strong>di</strong> istruzioni che<br />

consente ad esempio una gestione del compi<strong>la</strong>tore per l’ottimizzazione più<br />

aggressiva da parte <strong>dei</strong> <strong>processori</strong> RISC, potendo questi <strong>di</strong>sporre <strong>di</strong> un numero<br />

<strong>di</strong> registri nettamente superiore.<br />

Qualsiasi sia l’approccio utilizzato, i set <strong>di</strong> istruzioni <strong>di</strong> tutte le CPU sono ormai<br />

da tempo in grado, da un punto <strong>di</strong> vista funzionale, <strong>di</strong> eseguire qualsiasi tipo <strong>di</strong><br />

operazione. Il problema è, ancora una volta, quello <strong>di</strong> in<strong>di</strong>viduare soluzioni<br />

ottimizzate per ambiti specifici.<br />

Si pensi ad esempio alle applicazioni multime<strong>di</strong>ali. Come abbiamo già<br />

accennato al paragrafo 3.2.4 par<strong>la</strong>ndo delle unità vettoriali, avere a <strong>di</strong>sposizioni


124 Capitolo 3<br />

delle istruzioni ottimizzate in grado <strong>di</strong> sfruttare queste unità, porterà<br />

sicuramente gran<strong>di</strong> benefici. In questo caso si par<strong>la</strong> proprio <strong>di</strong> istruzioni SIMD.<br />

Un altro interessante campi <strong>di</strong> applicazione <strong>di</strong> queste istruzioni sono i calcoli<br />

matematici per applicazioni scientifiche.<br />

La prima architettura SIMD a essere <strong>di</strong>sponibile commercialmente fu<br />

l’architettura MMX realizzata da <strong>Intel</strong> ® .<br />

PROBLEMI<br />

Nell’evoluzione <strong>di</strong> un qualsiasi set <strong>di</strong> istruzioni, si pone un problema cruciale<br />

che ne ha da sempre influenzato lo sviluppo: è il problema del<strong>la</strong> retro-<br />

compatibilità. Se infatti voglio realizzare una nuova architettura, ma al<br />

contempo ho <strong>la</strong> necessità <strong>di</strong> porvi far funzionare i programmi attuali senza<br />

ricompi<strong>la</strong>rli (è quello cha auspica qualsiasi utente quando cambia il suo PC),<br />

devo assolutamente fare in modo <strong>di</strong> mantenere inalterato il comportamento<br />

delle istruzioni pre-esistenti.<br />

Di fronte a questa scelta, i vari produttori hanno avuto un approccio non sempre<br />

identico: c’è chi ha preferito mantenere <strong>la</strong> compatibilità a <strong>di</strong>scapito magari <strong>di</strong><br />

prestazioni o del prezzo, mentre c’è chi ha realizzato soluzioni completamente<br />

nuove, non retro compatibili.


Capitolo 4<br />

Il risparmio energetico<br />

Sono ormai lontani i giorni quando le prestazioni in termini <strong>di</strong> velocità erano<br />

l’unica cosa che contava per i progettisti <strong>di</strong> CPU.<br />

Basta infatti osservare i dati tecnici delle potenze <strong>di</strong>ssipate delle CPU <strong>dei</strong><br />

principali produttori per osservare come ci sia stata una inversione <strong>di</strong> tendenza<br />

molto drastica. Da quattro o cinque anni a questa parte il loro assorbimento è<br />

ridotto notevolmente, pur mantenendo un incremento delle prestazioni (es core<br />

2 duo consuma circa il 50% <strong>di</strong> energia rispetto al suo predecessore il<br />

Pentium ® 4)<br />

Ma quali sono i motivi <strong>di</strong> questa crescente attenzione? Forse solo gli aspetti<br />

ambientali?<br />

In realtà i motivi <strong>di</strong> fondo sono ben altri.<br />

La resistenza <strong>dei</strong> circuiti elettrici all’interno del<strong>la</strong> CPU genera calore e questo<br />

implica problemi <strong>di</strong> funzionamento <strong>dei</strong> <strong>di</strong>spositivi nonch’è <strong>la</strong> riduzione del<strong>la</strong><br />

loro vita me<strong>di</strong>a.<br />

In più, in una società sempre più “Mobile”, <strong>la</strong> necessità <strong>di</strong> utilizzare risorse<br />

limitate (batterie per i Portatili) per molto tempo mantenendo un sufficiente<br />

grado <strong>di</strong> prestazioni è <strong>di</strong>ventata sempre più un elemento essenziale.<br />

L’approccio tra<strong>di</strong>zionale che negli anni passati avevano i progettisti era legato<br />

più ad aspetti tecnologici: l’idea era quel<strong>la</strong> <strong>di</strong> miniaturizzare sempre più i


126 Capitolo 4<br />

transistor, permettendo così <strong>la</strong> riduzione del voltaggio operativo, che si traduce<br />

in minor <strong>di</strong>ssipazione termica.<br />

In realtà <strong>la</strong> miniaturizzazione ha portato si ad una riduzione del<strong>la</strong> potenza<br />

<strong>di</strong>ssipata per transistor, ma è anche vero che <strong>la</strong> miniaturizzazione ha permesso<br />

<strong>di</strong> aumentare il numero <strong>di</strong> transistor nel chip nonché <strong>di</strong> aumentare <strong>la</strong> frequenza<br />

<strong>di</strong> clock. Il bi<strong>la</strong>ncio energetico complessivo è pertanto sempre stato<br />

peggiorativo in termini <strong>di</strong> <strong>di</strong>ssipazione complessiva del Chip.<br />

Da alcuni anni a questa parte, i produttori sono molto attenti a trovare tecniche<br />

per ridurre il consumo <strong>di</strong> energia, e anche gli aspetti <strong>architetturali</strong> devono dare il<br />

loro contributo.<br />

Ci aspettiamo ad esempio che i <strong>processori</strong> <strong>di</strong> prossima generazione siano in<br />

grado <strong>di</strong> spegnere i transistor inutilizzati (sleep transistor), intere unità<br />

funzionali come <strong>dei</strong> segmenti <strong>di</strong> cache L2, nonché <strong>la</strong> possibilità <strong>di</strong> spegnere<br />

<strong>di</strong>namicamente interi core per risparmiare energia. Probabilmente accelereranno<br />

anche i core per carichi <strong>di</strong> <strong>la</strong>voro single-threaded (<strong>Intel</strong> ® EDAT, Enhanced<br />

Dynamic Acceleration Technology, tecnologia aspettata con i <strong>processori</strong> a 45<br />

nm Wolfdale e Yorkfield). Con molti <strong>processori</strong> che supportano già il carico<br />

<strong>di</strong>namico e <strong>la</strong> rego<strong>la</strong>zione del<strong>la</strong> velocità, questo è chiaramente il passo logico<br />

successivo.<br />

Data <strong>la</strong> natura più tecnologia che microarchitetturale del problema, in questa<br />

tesi si daranno so<strong>la</strong>mente cenni sul problema, senza <strong>la</strong> pretesa <strong>di</strong> una trattazione<br />

dettagliata ed esaustiva.


Capitolo 5<br />

Applicazione nei <strong>processori</strong> <strong>Intel</strong> ®<br />

5.1 I <strong>processori</strong> del<strong>la</strong> <strong>Intel</strong> ® Corporation<br />

<strong>Intel</strong> ® Corporation è ormai da anni l’azienda leader nel mercato <strong>dei</strong><br />

micro<strong>processori</strong> a 32 bit. È per questo che vogliamo approfon<strong>di</strong>re come questo<br />

produttore ha introdotto le architetture <strong>di</strong> cui abbiamo par<strong>la</strong>to nei paragrafi<br />

precedenti, soffermandoci via via ad osservare come esse sono state migliorate<br />

nelle varie famiglie <strong>di</strong> <strong>processori</strong> prodotti nell’ultimo ventennio.<br />

Nelle appen<strong>di</strong>ci A e B, viene illustrata una breve storia del colosso statunitense,<br />

nonché una cronistoria <strong>dei</strong> <strong>processori</strong> e del periodo <strong>di</strong> introduzione sul mercato.<br />

5.2 Modello Tick tock<br />

Lo sviluppo e l’uscita su mercato del <strong>processori</strong> del produttore americano<br />

<strong>Intel</strong> ® , seguono un approccio noto con i termini Tick e Tock [16]. Ogni anno<br />

<strong>Intel</strong> ® presenta una nuova generazione <strong>di</strong> <strong>processori</strong>, che possono o<br />

implementare un’architettura completamente nuova oppure essere costruiti<br />

utilizzando una nuova tecnologia produttiva più sofisticata rispetto a quanto in<br />

precedenza <strong>di</strong>sponibile. Prendendo come riferimento le cpu Nehalem (ovvero le<br />

ultime nate <strong>di</strong> casa <strong>Intel</strong> ® , note sul mercato con il nome <strong>di</strong> Core i7) a queste<br />

corrisponde una fase Tock, cioè quel<strong>la</strong> <strong>di</strong> una nuova generazione <strong>di</strong>


128 Capitolo 5<br />

microarchitettura completamente <strong>di</strong>fferente rispetto al<strong>la</strong> precedente. Lo stesso<br />

era accaduto 2 anni fa con il debutto delle cpu del<strong>la</strong> famiglia Merom, che hanno<br />

poi preso il nome commerciale <strong>di</strong> Core 2 Duo e Core 2 Quad a seconda delle<br />

versioni; in quel caso il cambio architetturale è avvenuto in sostituzione delle<br />

cpu Pentium ® D.<br />

Le fasi Tick in<strong>di</strong>cano l’utilizzo <strong>di</strong> un nuovo processo produttivo: le cpu<br />

Nehalem sono costruite con tecnologia a 45 nanometri, <strong>la</strong> stessa adottata dalle<br />

cpu del<strong>la</strong> famiglia Penryn (Core 2 Duo e Core 2 Quad) attualmente <strong>di</strong>sponibili<br />

in commercio. Al<strong>la</strong> fase Tick corrisponde tipicamente anche un refresh<br />

dell’architettura, con l’implementazione <strong>di</strong> alcune funzionalità<br />

complessivamente considerate minori; ad esempio, con le cpu Penryn ha<br />

debuttato <strong>la</strong> tecnologia produttiva a 45 nanometri e contestualmente sono state<br />

introdotte le istruzioni SSE4 non presenti nelle soluzioni del<strong>la</strong> famiglia Merom.<br />

L’evoluzione a 32 nanometri <strong>di</strong> tecnologia produttiva delle cpu Nehalem è nota<br />

con il nome <strong>di</strong> Westmere; i <strong>processori</strong> <strong>di</strong> questa famiglia debutteranno non<br />

prima del<strong>la</strong> fine <strong>di</strong> quest’anno, anche in questo caso con presumibili<br />

innovazioni e migliorie ma senza stravolgimenti dell’architettura.<br />

Per quale motivo <strong>Intel</strong> ® ha scelto <strong>di</strong> presentare le proprie soluzioni con questo<br />

tipo <strong>di</strong> cadenza? L’alternativa potrebbe essere quel<strong>la</strong> <strong>di</strong> introdurre nuove<br />

architetture <strong>di</strong> processore congiuntamente ad un nuovo processo produttivo, ma<br />

questa strada è ricca <strong>di</strong> numerose variabili che possono pregiu<strong>di</strong>care <strong>la</strong> riuscita<br />

<strong>di</strong> un progetto e storicamente non è stata quasi mai adottata. La scelta è quin<strong>di</strong><br />

quel<strong>la</strong> <strong>di</strong> presentare nuove architetture utilizzando tecnologia produttiva avviata


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 129<br />

da tempo, con <strong>la</strong> quale non si corrono rischi partico<strong>la</strong>ri <strong>di</strong> rese inferiori alle<br />

aspettative, utilizzando per i processi più sofisticati architetture che sono già<br />

state evolute e sviluppate da tempo.<br />

Figura 5.1 – Tick-tock in azione: Prima il “Tick” (anno 1) nel quale <strong>Intel</strong> ® sviluppa un<br />

nuovo processo tecnologico incrementando <strong>la</strong> densità <strong>dei</strong> transistori fino a conseguire<br />

miglioramento delle performance e dell’efficienza energetica con una so<strong>la</strong> rifinitura<br />

del<strong>la</strong> esistente microrchitettura. Segue poi il “Tock” (anno2) nel quale viene concepita<br />

una nuova microarchitettura per ottimizzare gli aggiornamenti tecnologici ora<br />

<strong>di</strong>sponibili[16].


130 Capitolo 5<br />

Figura 5.2-Per <strong>la</strong> sua politica <strong>di</strong> update <strong>Intel</strong> ® ha coniato il termine tick-tock<br />

(equivalente del tic-tac italiano). Nelle roadmap del<strong>la</strong> casa <strong>di</strong> Santa C<strong>la</strong>ra lo sta<strong>di</strong>o tick<br />

è rappresentato dal<strong>la</strong> fase <strong>di</strong> miglioramento dell’architettura pre-esistente,<br />

miglioramento che passa per l’ottimizzazione e <strong>la</strong> riduzione del processo produttivo. Lo<br />

sta<strong>di</strong>o tock prevede invece il <strong>la</strong>ncio <strong>di</strong> un’architettura completamente nuova, però<br />

realizzata con il processo produttivo del<strong>la</strong> fase precedente.<br />

5.3 Nomi delle architetture e re<strong>la</strong>tive CPU<br />

La seguente tabel<strong>la</strong> sintetizza le varie microarchitetture sviluppate da <strong>Intel</strong> ® fino<br />

ad oggi.<br />

Anno<br />

Nome<br />

Processori appartenenti<br />

Introduzione Architettura<br />

1978 8086/8088 <strong>Intel</strong> ® 8086<br />

<strong>Intel</strong> ® 8088<br />

1982 286 <strong>Intel</strong> ® 80286<br />

1985 386 <strong>Intel</strong> ® 80386<br />

1989 486 <strong>Intel</strong> ® 80486<br />

1993 Pentium <strong>Intel</strong> ® Pentium<br />

1995 P6 <strong>Intel</strong> ® Pentium ® Pro<br />

<strong>Intel</strong> ® Pentium ® II<br />

<strong>Intel</strong> ® Pentium ® II Xeon<br />

<strong>Intel</strong> ® Celeron<br />

<strong>Intel</strong> ® Pentium ® III<br />

<strong>Intel</strong> ® Pentium ® III Xeon<br />

2000 NetBurst <strong>Intel</strong> ® Pentium ® IV


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 131<br />

Anno<br />

Introduzione<br />

Nome<br />

Architettura<br />

Processori appartenenti<br />

<strong>Intel</strong> ® Xeon<br />

<strong>Intel</strong> ® Pentium ® M<br />

<strong>Intel</strong> ® Pentium ® D<br />

<strong>Intel</strong> ® Xeon Dual Core<br />

2006 Core <strong>Intel</strong> ® Core 2 Duo<br />

<strong>Intel</strong> ® Core 2 Quad<br />

<strong>Intel</strong> ® Xeon 51xx, 71xx, 53xx, 73xx, 54xx<br />

2008 Nehalem Core i7<br />

Tabel<strong>la</strong> 5.1 - Microarchitetture <strong>Intel</strong> ® e re<strong>la</strong>tivi <strong>processori</strong><br />

Per quanto riguarda <strong>la</strong> nomenc<strong>la</strong>tura <strong>dei</strong> <strong>processori</strong> <strong>Intel</strong>, è da osservare come<br />

ad ognuno <strong>di</strong> essi sono associati due nomi.<br />

• Nome commerciale: è il nome con cui il processore viene immesso sul<br />

mercato e viene assegnato nel momento in cui il prodotto viene<br />

commercializzato<br />

• Nome in Co<strong>di</strong>ce o “codename”: è il nome associato a ciascun<br />

processore durante le fase <strong>di</strong> sviluppo del<strong>la</strong> CPU stessa.<br />

5.4 Parallelismo “on Chip”<br />

5.4.1 Pipeline<br />

386<br />

La primor<strong>di</strong>ale implementazione del<strong>la</strong> pipeline si ha già dal processore 80386<br />

(1985) con una sud<strong>di</strong>visione dell’esecuzione delle istruzioni in due fasi:<br />

“Istruction decode” ed “execution units”.


132 Capitolo 5<br />

486<br />

INTEGER PIPELINE<br />

Il processore <strong>Intel</strong> ® 80486 (1989) aggiunge maggior capacità <strong>di</strong> esecuzione<br />

paralle<strong>la</strong> espandendo l’ “instruction decode” e l’ “execution units” in 5 sta<strong>di</strong><br />

pipelined. Ogni sta<strong>di</strong>o opera in parallelo agli altri, in modo tale che<br />

contemporaneamente risiedono 5 istruzioni nei 5 <strong>di</strong>versi sta<strong>di</strong> del<strong>la</strong> pipeline.<br />

Gli sta<strong>di</strong> delle pipeline <strong>di</strong> questa CPU sono illustrati nel<strong>la</strong> Figura 5.3:<br />

Figura 5.3 – La integer pipeline del processore 486[17]<br />

Le fasi <strong>di</strong> questa pipeline possono essere così sintetizzate[18]:<br />

• PF: Prefetch – Le istruzioni, a blocchi <strong>di</strong> 16 bytes, vengono richiamate<br />

dal<strong>la</strong> cache sul chip o dal<strong>la</strong> memoria in un buffer <strong>di</strong> prefetch buffer,<br />

recuperando circa 5 istruzioni per ogni fetch;<br />

• D1: Prima deco<strong>di</strong>fica – Vengono processati fino a tre byte <strong>di</strong> istruzioni<br />

al<strong>la</strong> volta; viene quin<strong>di</strong> determinata <strong>la</strong> lunghezza dell’istruzione e <strong>di</strong><br />

conseguenza posizionato il prefetch buffer per l’esecuzione dello step


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 133<br />

re<strong>la</strong>tivo al<strong>la</strong> istruzione successiva; Viene aggiunto un “extra cycles” nel<br />

caso <strong>di</strong> istruzioni con prefisso o operan<strong>di</strong> <strong>di</strong> 2 byte<br />

• D2: Seconda deco<strong>di</strong>fica – In questa fase viene effettivamente calco<strong>la</strong>to<br />

l’in<strong>di</strong>rizzo degli operan<strong>di</strong>; Istruzioni che contengono<br />

contemporaneamente un operando imme<strong>di</strong>ato e un <strong>di</strong>sp<strong>la</strong>cement, e<br />

anche coman<strong>di</strong> che utilizzano contemporaneamente in<strong>di</strong>rizzamenti <strong>di</strong><br />

base e in<strong>di</strong>cizzati vengono eseguiti in due cicli <strong>di</strong> clock<br />

• EX: Esecuzione – questa fase include anche il fetch degli operan<strong>di</strong> da<br />

registro e l’accesso ai dati su cache. Operazioni <strong>di</strong> Data Cache Hit sia<br />

per delle load che per le store, operazioni del<strong>la</strong> ALU con operan<strong>di</strong> e<br />

risultati tutti nei registri, possono essere eseguite in un ciclo; Sono<br />

invece necessari <strong>dei</strong> cicli extra per le istruzioni complesse (ad esempio<br />

un “reg-to-memory add” richiede 3 EX cycles: uno per il data fetch<br />

dal<strong>la</strong> cache, uno per l’effettiva operazione <strong>di</strong> add, e uno per scrivere i<br />

risultati nel<strong>la</strong> cache).<br />

• WB: Write back – ovvero <strong>la</strong> scrittura nei registri<br />

Possiamo vedere gli le varie fasi del<strong>la</strong> pipeline anche nello schema a blocchi <strong>di</strong><br />

questa CPU illustrato nel<strong>la</strong> Figura 5.4


134 Capitolo 5<br />

UNITÀ FP<br />

Figura 5.4 – Schema a blocchi del<strong>la</strong> CPU 486. [18]<br />

L’unità Floating point, ora integrata nel<strong>la</strong> CPU, prevede invece una pipeline a 8<br />

sta<strong>di</strong>. Essa è costituita dai primi 4 sta<strong>di</strong> del<strong>la</strong> pipeline integer F/D1/D2/EX,<br />

seguiti dai seguenti stati FP:<br />

• X1: execute-1<br />

• X2: exexute-2<br />

• WF: FP write-back<br />

• ER: error reporting<br />

La pipeline del 486 prevede una gestione <strong>dei</strong> salti elementare considerando<br />

sempre il salto come “non preso”. Questo comporta sempre <strong>la</strong> per<strong>di</strong>ta <strong>di</strong> 2 cicli<br />

ogni volta che viene mo<strong>di</strong>ficato il Program Counter: il salto viene infatti<br />

determinato nel<strong>la</strong> fase EX e il contenuto <strong>di</strong> D1 e D2 deve essere rimpiazzato.


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 135<br />

PENTIUM<br />

INTEGER<br />

Nel processore Pentium ® <strong>la</strong> pipeline rimane del<strong>la</strong> stessa profon<strong>di</strong>tà del 486, ma<br />

l’architetture <strong>di</strong>venta supersca<strong>la</strong>re: abbiamo infatti due “instruction pipeline”,<br />

definite “u” e “v”, che <strong>la</strong>vorano in parallelo. Entrambe le pipeline svolgono<br />

operazioni Integer, pertanto il processore risulta ora in grado <strong>di</strong> svolgere due<br />

istruzioni intere per ogni ciclo.<br />

Figura 5.5 – La integer pipeline del Pentium.[17]<br />

Le due pipe <strong>di</strong>fferiscono tra loro in quanto <strong>la</strong> “u” può svolgere qualsiasi<br />

istruzione dell’architettura x86, <strong>la</strong> “v” pipe esegue solo coman<strong>di</strong> semplici che<br />

non richiedono microco<strong>di</strong>ci <strong>di</strong> alcun tipo (harwired instructions).<br />

L’assegnamento in parallelo <strong>di</strong> due istruzioni sulle pipelines “u” e “v” viene<br />

chiamato “instruction pairing”.Se le istruzioni vengono assegnate a coppie al<strong>la</strong><br />

pipelines, l’istruzione sul<strong>la</strong> pipe “v” è sempre quel<strong>la</strong> che segue l’istruzione sul<strong>la</strong><br />

pipe “u”. Il fatto che le istruzioni <strong>di</strong> base (come ad esempio le operazioni ALU


136 Capitolo 5<br />

e MOV) siano ora realizzate cab<strong>la</strong>te fa sì che <strong>la</strong> loro velocità <strong>di</strong> esecuzione sia<br />

sostanzialmente aumentata. Inoltre tutte le microistruzioni sono state<br />

ottimizzate, ottenendo così un ulteriore aumento del<strong>la</strong> velocità <strong>di</strong> esecuzione. La<br />

struttura delle pipelines del<strong>la</strong> CPU i486 <strong>Intel</strong> ® è stata conservata ed ottimizzata<br />

nel processare Pentium, per ottenere un flusso più elevato.<br />

Figura 5.6 - Architettura interna del processore Pentium[17]<br />

Osservando lo schema a blocchi dell’architettura interna del Pentium ® <strong>di</strong> Figura<br />

5.6, possiamo osservare che <strong>la</strong> fase <strong>di</strong> Prefetch fa ora riferimento ad una “cache<br />

code” <strong>di</strong>stinta dal<strong>la</strong> cache <strong>dei</strong> dati. <strong>la</strong> separazione delle cache per co<strong>di</strong>ce e dati<br />

sul<strong>la</strong> CPU vengono evitati conflitti nel<strong>la</strong> cache quando vengono prelevati


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 137<br />

istruzioni con contemporanea lettura <strong>di</strong> dati. Due coppie in<strong>di</strong>pendenti <strong>di</strong><br />

prefetch buffers permettono <strong>la</strong> contemporanea esecuzione <strong>di</strong> prefetch e <strong>di</strong><br />

co<strong>di</strong>ce su entrambe le pipelines. I due prefetch buffers operano in<br />

sovrapposizione con il branch target buffer (BTB).<br />

Il BTB è l’unità funzionale <strong>di</strong> pre<strong>di</strong>zione <strong>dei</strong> salti, che serve per ridurre al<br />

minimo gli stalli del<strong>la</strong> pipelines a causa <strong>dei</strong> salti con<strong>di</strong>zionati. Dei due prefetch<br />

buffers, è attivo uno solo per volta, per prelevare istruzioni sequenziali. Ciò vale<br />

finchè non si preleva un'istruzione non sequenziale. In tale caso, il BTB viene<br />

utilizzato per prevedere se il "loop" sia da eseguire (taken) o da non eseguire<br />

(not taken). Il prefetch viene proseguito sequenzialmente solo nel caso in cui il<br />

loop venga valutato "not taken". Se il loop viene predetto come "taken", l'altro<br />

prefetch buffer viene chiamato in causa ed inizia a prelevare opcode come se il<br />

loop fosse già in esecuzione. Se poi <strong>la</strong> previsione si rive<strong>la</strong> errata, <strong>la</strong> pipeline<br />

viene svuotata, e il code prefetching prosegue alternativamente sull'altro<br />

prefetch buffer.<br />

Nel secondo step del<strong>la</strong> pipeline, <strong>la</strong> deco<strong>di</strong>fica delle istruzioni (D1), viene<br />

determinato il tipo <strong>di</strong> comando, e si decide se si possono passare alle integer<br />

pipeline una o due istruzioni. Il passaggio <strong>di</strong> istruzioni accoppiate viene<br />

determinato dalle seguenti regole:<br />

• le due istruzioni seguenti devono essere "coman<strong>di</strong> semplici",<br />

interamente cab<strong>la</strong>ti.<br />

• non devono esserci <strong>di</strong>pendenze <strong>di</strong> registro


138 Capitolo 5<br />

• istruzioni con prefisso (con l'eccezione <strong>di</strong> OFh in collegamento con<br />

istruzioni <strong>di</strong> loop con<strong>di</strong>zionate) possono essere eseguite solo dal<strong>la</strong> "u"<br />

pipe.<br />

• nei coman<strong>di</strong> eseguiti in parallelo non possono essere<br />

contemporaneamente presenti <strong>di</strong>sp<strong>la</strong>cement e operan<strong>di</strong> imme<strong>di</strong>ati.<br />

Nel secondo passo <strong>di</strong> deco<strong>di</strong>ficazione (D2) vengono determinati gli in<strong>di</strong>rizzi<br />

degli operan<strong>di</strong>. Al contrario <strong>di</strong> quanto avveniva per l'i486, le istruzioni che<br />

contengono contemporaneamente un operando imme<strong>di</strong>ate e un <strong>di</strong>sp<strong>la</strong>cement,<br />

nonché i coman<strong>di</strong> che utilizzano contemporaneamente in<strong>di</strong>rizzamenti <strong>di</strong> base e<br />

in<strong>di</strong>cizzati possono essere eseguiti in un solo ciclo.<br />

Nel<strong>la</strong> fase <strong>di</strong> esecuzione <strong>di</strong> una istruzione (EX) vengono eseguite una<br />

operazione ALU ed un ricorso al<strong>la</strong> cache. Coman<strong>di</strong> che specifichino sia<br />

l'operazione ALU che l'accesso al<strong>la</strong> cache richiedono più <strong>di</strong> un ciclo in questa<br />

fase. Nel<strong>la</strong> fase EX i coman<strong>di</strong> sul<strong>la</strong> "u" pipe e sul<strong>la</strong> "v" pipe vengono verificati<br />

per quanto riguarda <strong>la</strong> correttezza del<strong>la</strong> branch pre<strong>di</strong>ction. Un’eccezione sono i<br />

loop con<strong>di</strong>zionati, che vengono verificati solo nello step WB.<br />

L'ultimo sta<strong>di</strong>o <strong>di</strong> pipeline è il writeback (WB). I coman<strong>di</strong> eseguiti possono<br />

alterare lo stato del processo re e terminare l'esecuzione delle istruzioni. I loops<br />

con<strong>di</strong>zionati vengono verificati per quanto riguarda <strong>la</strong> correttezza del<strong>la</strong><br />

pre<strong>di</strong>zione del<strong>la</strong> sequenzialità. Nel corso delle <strong>di</strong>verse fasi, possono avvenire<br />

delle interruzioni <strong>di</strong> pipeline. È assicurato che le pipes "u" e "v" entrano sempre<br />

contemporaneamente in D1 e D2, e abbandonano tali fasi sempre in modo


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 139<br />

contemporaneo. Se in una delle due pipelines un comando viene eseguito con<br />

maggiore lentezza, automaticamente l'esecuzione del comando sul<strong>la</strong> pipe<br />

paralle<strong>la</strong> viene sospesa, in modo che le pipeline entrino sempre<br />

simultaneamente nel<strong>la</strong> fase EX. Una volta in fase EX, l'esecuzione<br />

dell'istruzione nel<strong>la</strong> pipe "u" può proseguire, mentre può essere messa in attesa<br />

un'istruzione nel<strong>la</strong> pipe "v". Nessuna nuova istruzione può entrare nel<strong>la</strong> fase EX<br />

finché le istruzioni in entrambe le pipelines abbiano raggiunto <strong>la</strong> fase EX.<br />

UNITÀ FP<br />

L’unità a virgo<strong>la</strong> mobile del processore Pentium ® è stata completamente<br />

rie<strong>la</strong>borata ed è implementata come pipeline a 8 sta<strong>di</strong> con adder, multiplier e<br />

<strong>di</strong>vider separati.<br />

Figura 5.7- LA FPU del processore Pentium[17]<br />

Come nelle FPU precedenti. si ottempera al<strong>la</strong> IEEE 754, ma anche al nuovo<br />

standard IEEE 854. La FPU è concepita in modo da eseguire un’operazione in<br />

virgo<strong>la</strong> mobile per ciclo. Sono possibili fino a due istruzioni per ciclo, ma <strong>la</strong>


140 Capitolo 5<br />

seconda deve essere FXCHG. cioè floating point exchange. I primi quattro sta<strong>di</strong><br />

del<strong>la</strong> pipeline vengono con<strong>di</strong>visi con <strong>la</strong> unità integer.<br />

La FP-pipeline a 8 sta<strong>di</strong> è strutturata come segue<br />

• PF: prefetch<br />

• Dl: deco<strong>di</strong>fica delle istruzioni<br />

• D2:generazione degli in<strong>di</strong>rizzi<br />

• EX: lettura <strong>di</strong> registri e memoria;<br />

conversione in formato FP esterno<br />

e scrittura in memoria<br />

• Xl: step 1 <strong>di</strong> esecuzione FP:<br />

conversione del formato dati FP esterno a quello interno<br />

scrittura degli operan<strong>di</strong> nell’ FP register file.<br />

• X2: step 2 <strong>di</strong> esecuzione FP.<br />

• WF: arrotondamento e scrittura del risultato FP nel register file<br />

• ER: segna<strong>la</strong>zione <strong>di</strong> errore o aggiornamento del<strong>la</strong> paro<strong>la</strong> <strong>di</strong> stato<br />

Le seguenti regole valgono per l’impartizione <strong>dei</strong> coman<strong>di</strong> FP 9<br />

:<br />

• In generale le istruzioni FP non possono essere eseguite in coppia con<br />

istruzioni integer, ma una certa misura <strong>di</strong> esecuzione paralle<strong>la</strong> è<br />

comunque possibile (concurrefit processing).<br />

• Se due istruzioni vengono trasmesse contemporaneamente una delle due<br />

deve essere l’istruzione FXCHG, mentre l’altra deve appartenere al<br />

9 Queste regole <strong>di</strong> base permettono <strong>di</strong> aggirare il collo <strong>di</strong> bottiglia che si genera<br />

attraverso l’architettura a catasta (stack) <strong>dei</strong> registri FP.


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 141<br />

gruppo F (FLD. FLD(i), FADD, FSUB. FMUL, FDIV, FCOM,<br />

FUCOM, FIST, FABS, FCHS).<br />

• Coman<strong>di</strong> <strong>di</strong>versi da FXCHG o da quelli appartenenti al gruppo F<br />

vengono impartiti al<strong>la</strong> FPU in modo sequenziale.<br />

• Coman<strong>di</strong> cui non segue imme<strong>di</strong>atamente l’istruzione FXCHG vengono<br />

impartiti singo<strong>la</strong>rmente.<br />

Nonostante l’architettura sia in massima parte un’architettura pipeline, è stata<br />

implementata una forma <strong>di</strong> sicurezza per il riconoscimento delle istruzioni (SIR<br />

safe instruction recognition). La SIR viene eseguita nel<strong>la</strong> fase Xl del<strong>la</strong> pipeline<br />

e serve a rive<strong>la</strong>re il potenziale <strong>di</strong> errore presente nell’istruzione FP da eseguire.<br />

Un’istruzione FP è considerata “safe” se non contiene alcuna con<strong>di</strong>zione <strong>di</strong><br />

eccezione FP, come overflow e underflow aritmetici, o non genera una<br />

con<strong>di</strong>zione <strong>di</strong> eccezione non corretta. “Safe” significa anche che non è<br />

necessario alcun microco<strong>di</strong>ce per arrivare a risultati speciali, e che il prossimo<br />

comando FP può concludere <strong>la</strong> fase EX del<strong>la</strong> pipeline. Se un’istruzione FP<br />

viene definita “unsafe” <strong>la</strong> successiva istruzione viene sospesa nel<strong>la</strong> fase EX<br />

finché l’attuale operazione non ha passato <strong>la</strong> fase ER. Ciò provoca un<br />

rallentamento pari a 4 cicli, anche se al<strong>la</strong> fine tale istruzione non dovesse affatto<br />

generare con<strong>di</strong>zioni <strong>di</strong> eccezione.<br />

MMX<br />

L’introduzione del<strong>la</strong> tecnologica MMX, una estensione del<strong>la</strong> <strong>Intel</strong> ®<br />

Architectural Instruction Set che <strong>di</strong>scuteremo al paragrafo 5.7.2, ha determinato<br />

anche una aggiunta <strong>di</strong> sta<strong>di</strong> al<strong>la</strong> pipeline. L’integrazione del<strong>la</strong> pipeline MMX


142 Capitolo 5<br />

con <strong>la</strong> integer pipeline è molto simile a quel<strong>la</strong> dell’unità Floating Point[19]. La<br />

Figura 5.8 mostra <strong>la</strong> struttura del<strong>la</strong> pipeline MMX del Pentium.<br />

Figura 5.8 – Struttura del<strong>la</strong> pipeline MMX [19]<br />

Il Pentium ® con tecnologia MMX introduce uno sta<strong>di</strong>o aggiuntivo al<strong>la</strong> integer<br />

pipeline. I byte <strong>di</strong> istruzioni sono pre-caricati dal<strong>la</strong> cache code nello sta<strong>di</strong>o <strong>di</strong><br />

Prefetch (PF) e sono analizzate come istruzioni nello stage <strong>di</strong> Fetch (F). Sempre<br />

nel<strong>la</strong> fase F vengono deco<strong>di</strong>ficati tutti i prefissi.<br />

L’analisi dell’istruzione è <strong>di</strong>visa dal<strong>la</strong> deco<strong>di</strong>fica dell’istruzione attraverso un<br />

buffer istruzioni <strong>di</strong> tipo FIFO (First In, First Out), situato tra gli sta<strong>di</strong> F e D1<br />

Il buffer permette <strong>di</strong> contenere fino a 4 istruzioni. Questo buffer FIFO è<br />

trasparente e non aggiunge <strong>la</strong>tenza aggiuntiva quando è vuoto.<br />

Durante ogni ciclo <strong>di</strong> clock, 2 istruzioni possono essere inserite nel buffer ( a<br />

seconda del<strong>la</strong> <strong>di</strong>sponibilità <strong>di</strong> byte <strong>di</strong> co<strong>di</strong>ce e <strong>di</strong> altri fattori come i prefissi. Le<br />

istruzioni sono estratte dal buffer FIFO a coppie e inviate allo stato D1. Dal<br />

momento che <strong>la</strong> velocità me<strong>di</strong>a dell’esecuzione delle istruzioni è minore <strong>di</strong> 2<br />

per clock il buffer è normalmente pieno. Finché il FIFO è pieno, esso può<br />

salvare ogni stallo che può capitare durante il fetch e l’analisi dell’istruzione. Se


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 143<br />

ci si imbatte in uno stallo <strong>di</strong> questo tipo, il FIFO evita che lo stallo si ripercuota<br />

sullo sta<strong>di</strong>o <strong>di</strong> esecuzione. Se il FIFO è vuoto, si innesca uno stallo dello sta<strong>di</strong>o<br />

<strong>di</strong> esecuzione, per carenza <strong>di</strong> istruzioni da eseguire.<br />

Figura 5.9 - Introduzione del Buffer FIFO e dello sta<strong>di</strong>o PF nel<strong>la</strong> pipeline MMX<br />

rispetto a quel<strong>la</strong> del Pentium ® [20]<br />

La Figura 5.10 mostra nel dettaglio <strong>la</strong> pipeline MMX del processore<br />

supersca<strong>la</strong>re Pentium ® e le con<strong>di</strong>zioni che generano gli stalli.


144 Capitolo 5<br />

Figura 5.10 - Flusso <strong>di</strong> istruzioni MMX nel processore Pentium ® con tecnologia MMX<br />

La Figura 5.11 mostra le unità funzionali, <strong>la</strong> <strong>la</strong>tenza, il throughput e l’execution<br />

pipe per ogni tipo <strong>di</strong> istruzione MMX.<br />

Figura 5.11 - Tipi <strong>di</strong> istruzioni MMX e re<strong>la</strong>tive unità funzionali [19]


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 145<br />

P6 FAMILY<br />

PENTIUM ® PRO<br />

L’architettura successiva al processore Pentium ® prende il nome <strong>di</strong> architettura<br />

P6 in quanto <strong>la</strong> sesta architettura <strong>dei</strong> <strong>processori</strong> <strong>Intel</strong> ® x86. Il primo esemp<strong>la</strong>re<br />

<strong>di</strong> questa architettura fu il Pentium ® Pro che incrementò il numero <strong>di</strong> stages<br />

del<strong>la</strong> pipeline da 5 a 12.<br />

Figura 5.12 - La pipeline del processore Pentium ® Pro [19]<br />

Con l’introduzione del Pentium ® Pro, viene introdotta nel<strong>la</strong> pipeline una nuova<br />

architettura <strong>di</strong>namica <strong>di</strong> esecuzione che nasce dall’applicazione <strong>di</strong> tecniche <strong>di</strong><br />

esecuzione specu<strong>la</strong>tiva, esecuzione out-of-order, ridenominazione hardware <strong>dei</strong><br />

registri e pre<strong>di</strong>zione <strong>dei</strong> salti <strong>di</strong> cui <strong>di</strong>scuteremo nei paragrafi seguenti. Per il<br />

momento osserviamo solo come il core dell’out-of-order del processore<br />

contiene <strong>di</strong>verse pipelines alle quali sono attaccate le execution unit integer,<br />

branch, floating-point e memory.<br />

Varie e <strong>di</strong>fferenti unità <strong>di</strong> esecuzione possono essere così raggruppate nel<strong>la</strong><br />

stessa pipeline.<br />

Per esempio una Integer ALU e <strong>la</strong> FPU (adder, multiplier and <strong>di</strong>vider)<br />

con<strong>di</strong>vidono <strong>la</strong> pipeline. La “data cache” è interal<strong>la</strong>cciata attraverso una<br />

“pseudo-dual ported”, in cui una porta è de<strong>di</strong>cata al<strong>la</strong> lettura e l’altra al<strong>la</strong>


146 Capitolo 5<br />

scrittura. Molte operazioni semplici (come integer ALU, ad<strong>di</strong>zioni e<br />

moltiplicazioni floating-point) possono essere inserite nel<strong>la</strong> pipeline con un<br />

throughput <strong>di</strong> una o due operazioni per ciclo <strong>di</strong> clock.<br />

Le <strong>di</strong>visioni floating-point non sono invece “pipelined”. Long <strong>la</strong>tency<br />

operations can proceed in parallel with short <strong>la</strong>tency operations.<br />

La pipeline del Pentium ® Pro <strong>di</strong> Figura 5.12 può essere raggruppata in tre macro<br />

blocchi:<br />

• In-order front-end,<br />

• Out-of-order core,<br />

• In-order retirement unit.<br />

In Order Front-End<br />

La Errore. L'origine riferimento non è stata trovata. mostra nel dettaglio gli<br />

elementi che appartengono a questo primo blocco.<br />

L’introduzione del concetto <strong>di</strong> esecuzione fuori or<strong>di</strong>ne impone, affinché si<br />

possano riscontrare <strong>dei</strong> miglioramenti <strong>di</strong> prestazioni, che ciascuno istruzione<br />

venga sud<strong>di</strong>visa in sufficienti µ-operazioni (chiamate in seguito µ-ops) pronte<br />

per essere eseguite Anche <strong>la</strong> corretta pre<strong>di</strong>zione <strong>dei</strong> salti e una deco<strong>di</strong>fica veloce<br />

sono essenziali ottenere le migliori prestazioni in uscita dell’ “in order front-<br />

end”. Nel paragrafo 5.4.3 verrà descritto più nel dettaglio il “Branch<br />

Pre<strong>di</strong>ction” e il BTB. Occupiamoci ora del<strong>la</strong> deco<strong>di</strong>fica.


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 147<br />

BTB0<br />

BTB1<br />

IFU0<br />

IFU1<br />

IFU2<br />

ID0<br />

IFU0: Instruction Fetch Unit<br />

IFU1: In this stage 16-byte instruction p<br />

The packets are aligned on<br />

IFU2: Instruction Predecode<br />

packets aligned on any boundary<br />

Figura 5.13 – In order FrontEnd del Pentium ® Pro [19]<br />

ID0: Instruction Decode.<br />

Durante ogni ciclo <strong>di</strong> clock, possono essere deco<strong>di</strong>ficate fino a 3 macro-<br />

istruzioni da parte dello sta<strong>di</strong>o ID1. Pertanto se l’istruzione è complessa o è più<br />

lunga <strong>di</strong> sette byte, il decoder è limitato a deco<strong>di</strong>ficare meno istruzioni.


148 Capitolo 5<br />

I decoders possono deco<strong>di</strong>ficare:<br />

• fino a 3 macroistruzioni per ciclo <strong>di</strong> clock<br />

• fino a 6 µ-ops per ciclo <strong>di</strong> clock<br />

• macro istruzioni fino a 7 byte <strong>di</strong> lunghezza<br />

Il Pentium ® Pro ha 3 deco<strong>di</strong>ficatori nello sta<strong>di</strong>o D1. Il primo è capace <strong>di</strong><br />

deco<strong>di</strong>ficare una macro istruzione in 4 o meno µ-ops in ogni ciclo <strong>di</strong> clock. Gli<br />

altri due possono ciascuno deco<strong>di</strong>ficare una istruzione in una µ-ops per ogni<br />

ciclo <strong>di</strong> clock.<br />

Istruzioni composte da più <strong>di</strong> 4 µ-ops impiegano più cicli per essere<br />

deco<strong>di</strong>ficate.<br />

Se le istruzioni sono in una sequenza tale da venir convertite in 4-1-1 µ-ops,<br />

viene incrementato il numero <strong>di</strong> istruzioni che possono essere deco<strong>di</strong>ficate per<br />

ogni ciclo <strong>di</strong> clock. In generale:<br />

• Istruzioni semplici nel formato registro-registro sono costituite da una<br />

µ-ops<br />

• Istruzioni <strong>di</strong> load prevedono una so<strong>la</strong> µ-ops<br />

• Istruzioni <strong>di</strong> store hanno 2 µ-ops<br />

• Istruzioni <strong>di</strong> semplice lettura mo<strong>di</strong>ficano 2 µ-ops<br />

• Istruzioni semplici nel<strong>la</strong> forma registro-memoria hanno da 2 a 3 µ-ops.<br />

• Istruzioni semplici read-mo<strong>di</strong>fy write hanno 4 µ-ops<br />

• Istruzioni complesse in generale hanno più <strong>di</strong> 4 µ-ops e pertanto<br />

necessitano <strong>di</strong>versi cicli per essere deco<strong>di</strong>ficati


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 149<br />

Out Of Order core<br />

Quando le µ-ops sono deco<strong>di</strong>ficate, esse vengono ri<strong>la</strong>sciate dal “front-end in-<br />

order” verso il “Reservation Station” (RS), con <strong>la</strong> quale iniziano gli stati del<br />

blocco “Out-of order”. Nel RS, le µ-ops aspettano finché i dati <strong>dei</strong> loro operan<strong>di</strong><br />

non sono <strong>di</strong>sponibili. Quando <strong>la</strong> µ-ops ha tutti i dati degli operan<strong>di</strong> <strong>di</strong>sponibili,<br />

<strong>la</strong> µ-ops viene mandata dal RS all’execution unit. Se una µ-ops entra in RS con<br />

i dati già tutti <strong>di</strong>sponibili ed è <strong>di</strong>sponibile l’execution unit appropriata, <strong>la</strong> µ-ops<br />

viene inviata all’execution unit imme<strong>di</strong>atamente. In questo caso, le µ-ops non<br />

verranno spesi extra cicli <strong>di</strong> clock nel RS. Tutte le unità <strong>di</strong> esecuzione sono<br />

raggruppate sulle porte <strong>di</strong> uscita dell’RS. La Figura 5.14 mostra lo schema <strong>di</strong><br />

questo blocco, mentre <strong>la</strong> Figura 5.15 mostra l’associazione delle execution unit<br />

con le varie porte.<br />

Figura 5.14 - L'Out-of order Core del Pentium ® Pro [19]


150 Capitolo 5<br />

In order retirement unit<br />

Figura 5.15 - Execution units del Pentium ® Pro. [19]<br />

Quando le µ-ops sono state eseguite vengono salvate nel Re-Order Buffer<br />

(ROB) ed attendono il retirement. In questo sta<strong>di</strong>o del<strong>la</strong> pipeline, tutti i valori<br />

<strong>dei</strong> dati sono scritti nel<strong>la</strong> memoria e tutte le µ-ops sono completate in or<strong>di</strong>ne, 3<br />

al<strong>la</strong> volta. La Figura 5.16 mostra nel dettaglio questa sezione.<br />

Figura 5.16 - Retirement unit del Pentium ® Pro


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 151<br />

PENTIUM ® II<br />

Il Pentium ® II usa <strong>la</strong> stessa pipeline del Pentium ® Pro, ma integra anche le<br />

funzioni MMX già introdotte nel Pentium. La Figura 5.17 mostra l’aggiunta<br />

del<strong>la</strong> tecnologia MMX rispetto alle execution unit del Pentium ® pro.<br />

PENTIUM ® III<br />

Figura 5.17 - Execution units del Pentium ® II<br />

La pipeline del Pentium ® III resta praticamente invariata. Si sono solo aggiunte<br />

delle execution unit in grado <strong>di</strong> eseguire le istruzioni SIMD (ve<strong>di</strong> paragrafo<br />

5.7.2) ed una nuova unità Floating Point.


152 Capitolo 5<br />

Figura 5.18 - Architettura del Pentium ® II e del Pentium ® III [21]<br />

Figura 5.19 - Execution unit e porte del core Out-of-order del Pentium ® III [21]


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 153<br />

Figura 5.20 – Execution Unit del Pentium ® III. Per i tempi <strong>di</strong> <strong>la</strong>tenza delle unità SIMD,<br />

si rimanda all’appen<strong>di</strong>ce D del manuale <strong>Intel</strong> ® Architecture Optimization Reference<br />

Manual [21].


154 Capitolo 5<br />

NETBURST<br />

Nel 2000 con il Pentium ® 4 viene introdotta da <strong>Intel</strong> ® una nuova<br />

microarchitettura chiamata NetBurst. Gli obiettivi principali del progetto <strong>di</strong><br />

questa nuova microarchitettura erano fondamentalmente 2:<br />

Eseguire sia applicazioni IA-32 anche obsolete che nuove applicazioni basate<br />

sul<strong>la</strong> tecnologia SIMD con un alto Throughput<br />

Operare ad alte frequenze <strong>di</strong> clock e consentire nel futuro <strong>di</strong> aumentare le<br />

prestazioni aumentando <strong>la</strong> frequenza <strong>di</strong> clock stessa.<br />

L’architettura NetBurst è stata sviluppata infatti nel periodo in cui quando <strong>la</strong><br />

strada maestra per aumentare le prestazioni sembrava l’innalzamento del<strong>la</strong><br />

frequenza operativa. Si trattava infatti <strong>di</strong> un’architettura nata per spingere il<br />

processore fino a frequenze <strong>di</strong> 10 GHz.<br />

Per ottenere questo, il progetto prevedeva una pipeline con queste<br />

caratteristiche:<br />

Elevata profon<strong>di</strong>tà 10<br />

con parti funzionanti anche a <strong>di</strong>verse frequenze <strong>di</strong> clock.<br />

Ottimizzazione per i casi comuni delle istruzioni usate frequentemente: le<br />

istruzioni più frequentemente eseguite in circostanze comuni (come un cache<br />

hit) sono deco<strong>di</strong>ficate efficientemente ed eseguite con una bassa <strong>la</strong>tenza.<br />

Impiego <strong>di</strong> tecniche per ridurre le penalità in caso <strong>di</strong> stallo; tra cui esecuzioni<br />

parallele, buffering ed esecuzioni specu<strong>la</strong>tiva. La microarchitettura esegue le<br />

10 Il primo esemp<strong>la</strong>re del Pentium 4 aveva una profon<strong>di</strong>tà del<strong>la</strong> pipeline <strong>di</strong> 20 sta<strong>di</strong>. Tra<br />

i vari <strong>processori</strong> con architettura NetBurst si è arrivati fino a 31 sta<strong>di</strong>. <strong>Intel</strong> par<strong>la</strong> <strong>di</strong><br />

Hyper Pipelined Technology.


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 155<br />

istruzioni <strong>di</strong>namicamente e fuori or<strong>di</strong>ne, in modo che il tempo necessario<br />

all’esecuzione <strong>di</strong> ogni istruzione non sia sempre deterministico.<br />

Figura 5.21 - Microarchitettura <strong>Intel</strong> ® NetBurst [22]<br />

Come nelle precedent architetture l’approccio è quello <strong>di</strong> raggruppare gli sta<strong>di</strong><br />

del<strong>la</strong> Pipeline in 3 blocchi.<br />

In Order Front End<br />

Il front end del<strong>la</strong> microarchitettura NetBurst consiste <strong>di</strong> due parti:<br />

• fetch/decode unit<br />

• execution trace cache


156 Capitolo 5<br />

Esse eseguono le seguenti operazioni:<br />

• Prefetch delle istruzioni IA32 che sono probabilmente da eseguire<br />

• Fetch delle istruzioni richieste e che non sono state prevaricate<br />

• Deco<strong>di</strong>fica delle istruzioni in µops<br />

• Generazione <strong>di</strong> microco<strong>di</strong>ce per istruzioni complesse e co<strong>di</strong>ce special-<br />

purpose<br />

• Recapito delle istruzioni deco<strong>di</strong>ficate attraverso l’execution trace cache<br />

• Pre<strong>di</strong>zione <strong>dei</strong> salti usando algoritmi avanzati<br />

Il Front end è stato progettato per rispondere in partico<strong>la</strong>re a 2 problemi che<br />

sono sorgenti <strong>di</strong> ritardo:<br />

• Il tempo richiesto per deco<strong>di</strong>ficare le istruzioni caricate dal<strong>la</strong><br />

destinazione<br />

• La <strong>la</strong>rghezza <strong>di</strong> banda per <strong>la</strong> deco<strong>di</strong>fica sprecata a causa <strong>di</strong> salti o a salti<br />

<strong>di</strong> destinazione a metà <strong>di</strong> una cache line<br />

Le istruzioni sono caricate e deco<strong>di</strong>ficate da meccanismo d tras<strong>la</strong>zione.<br />

Quest’ultimo sistema le istruzioni deco<strong>di</strong>ficate in sequenze <strong>di</strong> µ-ops chiamate<br />

tracce. Queste tracce sono salvate nell’ “Execution Trace Cache”.<br />

Quest’ultimo salva le µ-ops nel percorso del flusso <strong>di</strong> esecuzione; nel<strong>la</strong> stessa<br />

cache line è salvato anche il risultato <strong>dei</strong> salti del co<strong>di</strong>ce.<br />

Questo incrementa il flusso <strong>di</strong> istruzioni dal<strong>la</strong> cache e permette il miglior uso<br />

dello spazio globale <strong>di</strong> salvataggio del<strong>la</strong> stessa in quanto non memorizza più le<br />

istruzioni che sono state evitate da un salto e quin<strong>di</strong> mai eseguite.


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 157<br />

Il trace cache può <strong>di</strong>stribuire fino a 3 µ-ops per clock all’execution core.<br />

“Execution trace cache” e “Trans<strong>la</strong>tion engine” hanno in comune hardware<br />

de<strong>di</strong>cato al<strong>la</strong> pre<strong>di</strong>zione <strong>dei</strong> salti. La destinazione <strong>dei</strong> salti sono predetti in base<br />

all’in<strong>di</strong>rizzo lineare usando <strong>la</strong> logica <strong>di</strong> branch pre<strong>di</strong>ction ed effettuando il fetch<br />

appena possibile.<br />

La destinazione del salto è caricata dall’execution trace cache se era stata<br />

salvata, altrimenti viene caricata dal<strong>la</strong> gerarchia <strong>di</strong> memoria.<br />

Prefetch<br />

Sono supportati 3 meccanismi <strong>di</strong> prefetch:<br />

• Un “Hardware Instruction Fetcher” effettua in automatico il prefetch<br />

delle istruzioni<br />

• Un meccanismo hardware che automaticamente esegue il Fetch <strong>dei</strong> dati<br />

e delle istruzioni nel<strong>la</strong> cache <strong>di</strong> secondo livello unificata.<br />

• Un meccanismo che esegue il fetch solo <strong>di</strong> dati che include due<br />

componenti:<br />

1. Meccanismo hardware per effettuare il fetch delle linee <strong>di</strong><br />

cache a<strong>di</strong>acenti utilizzando un settore <strong>di</strong> 128 Byte che contiene<br />

i dati vicini ad una cache line miss (normalmente si par<strong>la</strong> <strong>di</strong><br />

Adjacent Cache Line Prefech)<br />

2. Un meccanismo software che consente <strong>di</strong> eseguire il prefetch<br />

<strong>dei</strong> dati tramite apposite istruzioni


158 Capitolo 5<br />

Execution Trace Cache<br />

L’ “Execution Trace Cache” (TC) è <strong>la</strong> prima cache <strong>di</strong> istruzioni nel<strong>la</strong><br />

microarchitettura NetBurst. The TC salva le µ-ops ottenute dal<strong>la</strong> deco<strong>di</strong>fica<br />

delle istruzioni IA-32.<br />

Nel Pentium ® 4, l’implementazione del TC può salvare fino a 12K µ-ops e può<br />

<strong>di</strong>stribuire fino a 3 µ-ops per ciclo. TC non salva tutte le µ-ops che devono<br />

essere eseguite: in alcune situazioni l’execution core necessita <strong>di</strong> eseguire un<br />

flusso <strong>di</strong> microco<strong>di</strong>ce invece delle traces <strong>di</strong> µ-op che sono salvate nel trace<br />

cache.<br />

Il Pentium ® 4 è ottimizzato in modo che le istruzioni IA32 <strong>di</strong> frequente utilizzo<br />

escono dal trace cache, mentre solo poche istruzioni richiedono microco<strong>di</strong>ce<br />

ROM.<br />

Out Of Order supersca<strong>la</strong>r execution unit<br />

La capacità del core <strong>di</strong> eseguire istruzioni fuori or<strong>di</strong>ne è un fattore chiave per il<br />

parallelismo. Questa caratteristica abilita il processore a rior<strong>di</strong>nare le istruzioni<br />

in modo che se una µ-ops è ritardata in attesa <strong>di</strong> dati o a causa del<strong>la</strong> contesa <strong>di</strong><br />

risorse, le altre µ-ops che nel<strong>la</strong> sequenza del programma appaiono<br />

successivamente, possono essere processate prima. Questo implica che quando<br />

una porzione del<strong>la</strong> pipeline necessita <strong>di</strong> un ritardo, quest’ultimo può essere<br />

coperto da altre operazioni che possono essere eseguite in parallelo o<br />

dall’esecuzione <strong>di</strong> µ-ops in coda nel buffer.<br />

Il core è progettato per facilitare l’esecuzione in parallelo. Esso può <strong>di</strong>stribuire<br />

fino a 6 µ-ops per ciclo attraverso le porte <strong>di</strong> uscita (Figura 5.22)


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 159<br />

Da notare come 6 µ-ops per ciclo eccedono <strong>la</strong> <strong>la</strong>rghezza <strong>di</strong> banda del trace<br />

cache e dell’unità <strong>di</strong> retirement. La maggior <strong>la</strong>rghezza <strong>di</strong> banda del core<br />

permette <strong>di</strong> gestire queste situazioni.<br />

La maggior parte delle unità <strong>di</strong> esecuzione possono iniziare l’esecuzione <strong>di</strong> una<br />

nuova µ-op ogni ciclo in modo che <strong>di</strong>verse istruzioni possono attraversare nello<br />

stesso tempo <strong>la</strong> pipeline. Alcune istruzioni ALU possono essere avviate con una<br />

frequenza <strong>di</strong> 2 per ciclo 11<br />

; <strong>di</strong>verse istruzioni FP iniziano invece ogni 2 cicli.<br />

Infine le µ-ops possono iniziare ad essere eseguite fuori or<strong>di</strong>ne non appena i dati<br />

in ingresso sono pronti e le risorse <strong>di</strong>sponibili.<br />

Figura 5.22- Execution Unit e porte del<strong>la</strong> architettura NetBurst. [22]<br />

11 <strong>Intel</strong> chiama questa tecnologia “Rapid Execution Engine”


160 Capitolo 5<br />

In order retirement unit<br />

La “retirement unit” riceve i risultati dell’esecuzione <strong>di</strong> µ-ops dall’execution<br />

core e processa i risultati in modo che lo stato architetturale sia aggiornato in<br />

accordo con <strong>la</strong> corretta sequenza del programma originale. Per una esecuzione<br />

semanticamente corretta, i risultati delle istruzioni IA-32 devono essere<br />

processati nell’or<strong>di</strong>ne originale del programma prima che l’istruzione sia<br />

considerata “retired”.<br />

Quando una µ-op è completata e viene scritto il risultato nel<strong>la</strong> destinazione, essa<br />

viene ritirata. Possono essere ritirate fino a 3 µ-ops per ciclo. Il reorder buffer<br />

(ROB) è l’unità del processore che memorizza le µ-ops completate, aggiorna lo<br />

stato architetturale e gestisce l’or<strong>di</strong>ne delle eccezioni.<br />

La retirement unit tiene anche traccia <strong>dei</strong> salti e invia informazioni sulle<br />

destinazioni degli stessi al BTB. Questo aggiorna così il “Branch History”. La<br />

Figura 5.21 illustra i percorsi che più frequentemente vengono eseguiti<br />

all’interno del<strong>la</strong> microarchitettura NetBurst: l’esecuzione <strong>di</strong> un loop che<br />

interagisce con <strong>la</strong> gerarchia <strong>di</strong> cache multilivello e il Bus <strong>di</strong> sistema.


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 161<br />

CORE<br />

Figura 5.23 - Schema a blocchi dell'architettura del Pentium ® 4 [23]<br />

Con <strong>la</strong> microarchitettura Core, <strong>Intel</strong> ® introduce <strong>di</strong>verse innovazioni per poter<br />

conseguire alte prestazioni e allo stesso tempo garantire efficienza nel consumo<br />

energetico. Viene in partico<strong>la</strong>re introdotto il concetto <strong>di</strong> “<strong>Intel</strong> ® Wide Dynamic<br />

Execution” che permette <strong>di</strong> caricare, <strong>di</strong>stribuire ed eseguire istruzioni con una<br />

ampia <strong>la</strong>rghezza <strong>di</strong> banda e completare fino a 4 istruzioni per ciclo <strong>di</strong> clock per<br />

ogni core. Le sue caratteristiche principali sono:<br />

• pipeline efficiente a 14 sta<strong>di</strong><br />

• 3 ALU<br />

• 4 deco<strong>di</strong>ficatori in grado <strong>di</strong> deco<strong>di</strong>ficare fino a 5 istruzioni per ciclo


162 Capitolo 5<br />

• Tecniche <strong>di</strong> Macro-fusion e micro-fusion per aumentare il front-end<br />

throughput<br />

• Velocità <strong>di</strong> picco <strong>di</strong> emissione fino a 6 µ-ops per ciclo<br />

• Picco del<strong>la</strong> <strong>la</strong>rghezza <strong>di</strong> banda <strong>di</strong> completamento fino a 4 µ-ops per<br />

ciclo<br />

• Branch pre<strong>di</strong>ction evoluto<br />

• Stack pointer tracker per migliorare l’efficienza dell’esecuzione <strong>di</strong><br />

entrate ed uscite delle funzioni/procedure<br />

La pipeline del<strong>la</strong> microarchitettura Core contiene I seguenti elementi:<br />

• InOrder front end: lo streams <strong>di</strong> istruzioni viene caricato dal<strong>la</strong> memoria,<br />

deco<strong>di</strong>ficato in µ-ops da 4 decoders e inviato al Out-of-Order Execution<br />

core.<br />

• out-of-order supersca<strong>la</strong>r execution core: permette <strong>di</strong> completare fino a 6<br />

µ-ops per ciclo e rior<strong>di</strong>nare le µ-ops da eseguire appena sono<br />

<strong>di</strong>sponibili i dati e le risorse <strong>di</strong> esecuzione.<br />

• in-order retirement unit: garantisce che il risultato delle esecuzioni delle<br />

µ-ops sia processato e che lo stato architetturale venga aggiornato in<br />

accordo con l’or<strong>di</strong>ne originale del programma.<br />

Nel<strong>la</strong> Figura 5.24 è mostrato lo schema a blocchi del<strong>la</strong> pipeline Core.


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 163<br />

Figura 5.24 - Funzionamento del<strong>la</strong> pipeline del<strong>la</strong> microarchitettura <strong>Intel</strong> ® Core[24]<br />

FRONT END<br />

Il front end deve provvedere al<strong>la</strong> deco<strong>di</strong>fica <strong>di</strong> istruzioni (µ-ops) e sostenere il<br />

flusso <strong>di</strong> 6 µ-ops da fornire al motore out-of-order.<br />

I componenti del front end, le loro funzioni e l’impatto che hanno sulle<br />

prestazioni sono descritte nel<strong>la</strong> Figura 5.25.


164 Capitolo 5<br />

Figura 5.25- Elementi del Front End del<strong>la</strong> microarchitettura Core [24]<br />

EXECUTION CORE<br />

L’execution Core del<strong>la</strong> microarchitettura <strong>Intel</strong> ® Core è supersca<strong>la</strong>re e può<br />

processare istruzioni fuori or<strong>di</strong>ne. Quando una catena <strong>di</strong> <strong>di</strong>pendenze impone al<strong>la</strong><br />

macchina <strong>di</strong> aspettare a causa <strong>di</strong> una risorsa (come per esempio second-level<br />

data cache line), l’execution core esegue altre istruzioni. Questo incrementa <strong>la</strong><br />

velocità complessiva delle istruzioni eseguite per ciclo (IPC).


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 165<br />

I componenti principali che permettono questo tipo <strong>di</strong> esecuzione sono:<br />

• Renamer: Muove le µ-ops dal front end verso l’execution core. Esso<br />

effettua anche <strong>la</strong> ridenominazione <strong>dei</strong> registri <strong>architetturali</strong> in un ampio<br />

set <strong>di</strong> registri micro<strong>architetturali</strong>. La Ridenominazione <strong>dei</strong> registri<br />

elimina false <strong>di</strong>pendenze note, come i rischi <strong>di</strong> read-after-read e write-<br />

after-read.<br />

• Reorder Buffer (ROB): trattiene le µ-ops nei vari sta<strong>di</strong> <strong>di</strong><br />

completamento, bufferizza quelle completate, aggiorna lo stato<br />

architetturale in or<strong>di</strong>ne e gestisce l’or<strong>di</strong>ne delle eccezioni. Il ROB ha 96<br />

entries.<br />

• Reservation Station (RS): Accoda µ-ops finché tutti gli operan<strong>di</strong><br />

sorgente sono pronti, schedu<strong>la</strong> e <strong>di</strong>stribuisce le µ-ops pronte alle unità<br />

<strong>di</strong> esecuzione <strong>di</strong>sponibili. RS ha 32 entries.<br />

Lo sta<strong>di</strong>o iniziale del core out of order muove le µ-ops dal front end verso il<br />

ROB and RS. In questo processo, compie i seguenti passi:<br />

• Alloca risorse per le µ-ops (ad esempio queste risorse possono essere<br />

load or store buffers).<br />

• Associa ogni µ-op all’appropriata porta.<br />

• Rinomina sorgente e destinazione delle µ-ops, abilitando l’esecuzione<br />

fuori or<strong>di</strong>ne.<br />

• Recupera i dati delle µ-ops quando essi sono un valore imme<strong>di</strong>ato o il<br />

valore <strong>di</strong> un registro che è già stato calco<strong>la</strong>to.


166 Capitolo 5<br />

Lo schedu<strong>la</strong>tore può <strong>di</strong>stribuire fino a 6 µ-ops per ciclo attraverso le issue ports.<br />

Queste ultime sono descritte nel<strong>la</strong> Figura 5.26, mostrando i tempi <strong>di</strong> <strong>la</strong>tenza, il<br />

throughput delle comuni operazioni integer e FP per ciascuna porta espressi in<br />

cicli.<br />

Figura 5.26 - Issue ports del<strong>la</strong> Microarchitettura <strong>Intel</strong> ® Core. La tabel<strong>la</strong> mostra I dati<br />

per due modelli <strong>di</strong> processore. [24]


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 167<br />

In ogni ciclo, l’RS può <strong>di</strong>stribuire fino a 6 µ-ops. Ogni ciclo possono essere<br />

scritti all’in<strong>di</strong>etro fino a 4 risultati su RS e ROB, in modo che possano essere<br />

già utilizzati al prossimo ciclo <strong>di</strong> clock dall’RS.<br />

L’execution core contiene i 3 seguenti execution stack<br />

• SIMD integer<br />

• regu<strong>la</strong>r integer<br />

• x87/SIMD floating point<br />

Esso contiene poi i collegamenti da e per <strong>la</strong> memoria come illustrato in Figura<br />

5.27<br />

Figura 5.27 - Execution core del<strong>la</strong> microarchitettura <strong>Intel</strong> ® Core [24]<br />

Si noti <strong>la</strong> presenza <strong>di</strong> due blocchi scuri nei percorsi che collegano le Integer e le<br />

Integer SIMD con l’unità FP. Questi blocchi in<strong>di</strong>cano <strong>la</strong> necessità <strong>di</strong> inserire un<br />

ritardo noto col nome <strong>di</strong> “bypass de<strong>la</strong>y”. Anche i dati dal<strong>la</strong> cache L1 verso il FP<br />

presentano un ciclo extra <strong>di</strong> <strong>la</strong>tenza .


168 Capitolo 5<br />

NEHALEM<br />

La microarchitettura Nehalem mantiene <strong>la</strong> pipeline a 4 vie sviluppata nel<strong>la</strong><br />

microarchitettura Core a 65nm. La Figura 5.28 illustra i componenti <strong>di</strong> base<br />

del<strong>la</strong> pipeline del<strong>la</strong> Nehalem implementata nei <strong>processori</strong> <strong>Intel</strong> ® Core i7,<br />

mostrando però solo 2 <strong>dei</strong> quattro core presenti in queste CPU.<br />

Figura 5.28 - Funzionamento del<strong>la</strong> pipeline del<strong>la</strong> microarchitettura <strong>Intel</strong> ® Nehalem<br />

[24]


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 169<br />

La lunghezza del<strong>la</strong> pipeline è <strong>di</strong> due cicli più lunga rispetto al processore <strong>Intel</strong> ®<br />

Core 2 a 45nm, misura ottenibile me<strong>di</strong>ante il ritardo che si verifica in caso <strong>di</strong><br />

errata pre<strong>di</strong>zione del salto.<br />

Il front end può deco<strong>di</strong>ficare fino a 4 istruzioni in un ciclo e supporta 2<br />

hardware threads attraverso <strong>la</strong> deco<strong>di</strong>fica <strong>di</strong> un streams <strong>di</strong> istruzioni tra due<br />

<strong>processori</strong> logici in cicli alternati. Il front end include miglioramenti nel<strong>la</strong><br />

gestione <strong>dei</strong> branch, nel rilevamento <strong>dei</strong> loop, MSROM throughput, etc<br />

Il reservation station può <strong>di</strong>stribuire fino a 6 µ-ops in un ciclo attraverso 6 issue<br />

ports (5 issue ports sono mostrate in Figura 5.28; le operazioni <strong>di</strong> store<br />

utilizzano porte separate per salvare dati ed in<strong>di</strong>rizzi: nel <strong>di</strong>agramma queste<br />

porta sono mostrate come una so<strong>la</strong>).<br />

L’ out-of-order engine ha molte unità <strong>di</strong> esecuzione che sono <strong>di</strong>sposte in 3<br />

execution cluster. Essa può ritirare 4 µ-ops in un ciclo come il suo predecessore<br />

FRONT END<br />

La Figura 5.29 mostra i componenti chiave del front end del<strong>la</strong> microarchitettura<br />

Nehalem.<br />

L’ “instruction fetch unit” (IFU) può caricare fino a 16 bytes <strong>di</strong> istruzioni<br />

allineate al bytes ogni ciclo dal<strong>la</strong> cache istruzioni verso l’ “instruction length<br />

decoder” (ILD). L’ “instruction queue” (IQ) bufferizza le istruzioni processate<br />

dall’ILD e può <strong>di</strong>stribuire all’ “Instruction Decoder” fino a 4 istruzioni in un<br />

ciclo.


170 Capitolo 5<br />

Figura 5.29 - Front end del<strong>la</strong> pipeline del<strong>la</strong> microarchitettura Nehalem [24]<br />

L’ “instruction decoder” ha 3 unità <strong>di</strong> deco<strong>di</strong>fica che possono deco<strong>di</strong>ficare una<br />

istruzione semplice per ciclo ciascuna. L’altra unità <strong>di</strong> deco<strong>di</strong>fica può<br />

deco<strong>di</strong>ficare una istruzione ogni ciclo, sia essa una istruzione semplice o una<br />

istruzione complessa costituita da <strong>di</strong>verse µ-ops. Istruzioni costituite da più <strong>di</strong> 4<br />

µ-ops sono consegnate dall’ MSROM.<br />

Fino a 4 µ-ops possono essere consegnate ad ogni ciclo all’ “instruction<br />

decoder queue” (IDQ).<br />

Un “loop stream detector” è posizionato nell’ IDQ per migliorare il consumo <strong>di</strong><br />

Potenza e l’efficienza del front end per i loop con una basso numero <strong>di</strong><br />

istruzioni.<br />

L’instruction decoder supporta <strong>la</strong> tecnica detta <strong>di</strong> Microsfusion per migliorare il<br />

throughput del front end, aumentando l’effettiva <strong>di</strong>mensione delle code nello<br />

schedu<strong>la</strong>tore (RS) e nel ROB. Il regole del Microfusion sono simili a quelle<br />

del<strong>la</strong> microarchitettura Core.


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 171<br />

L’ “instruction queue” supporta invece <strong>la</strong> macro-fusion per combinare istruzioni<br />

a<strong>di</strong>acenti in una µ-op quando possibile. Rispetto al<strong>la</strong> microarchitettura Core <strong>la</strong><br />

Macro-fusion è ora supportata da <strong>di</strong>verse istruzioni e anche nel<strong>la</strong> modalità a 64<br />

bit.<br />

EXECUTION ENGINE<br />

L’ IDQ (Figura 5.29) consegna il flusso <strong>di</strong> µ-ops allo sta<strong>di</strong>o<br />

“allocation/renaming” del<strong>la</strong> pipeline (Figura 5.28). L’out-of-order engine<br />

supporta fino a 128 µ-ops contemporaneamente. Ogni µ-ops deve essere<br />

allocata con le seguenti risorse: un’entry nel re-order buffer (ROB), un’entry nel<br />

reservation station (RS), ed una load/store buffer se è richiesto un accesso al<strong>la</strong><br />

memoria.<br />

L’ “allocator” rinomina anche i registri per ogni µ-ops. I dati <strong>di</strong> ingresso<br />

associati con le µ-ops sono generalmente letti o dal ROB o dal “retired regiter<br />

file”.<br />

La profon<strong>di</strong>tà del RS è espansa a 36 entry (rispetto alle 32 entries delle<br />

precedenti generazioni). Esso può consegnare fino a 6 µ-ops in un ciclo se le µ-<br />

ops sono pronte per essere eseguite. RS consegna ogni µ-op attraverso una issue<br />

port verso il cluster <strong>di</strong> esecuzione specifico<br />

Ogni cluster può contenere una raccolta <strong>di</strong> unità <strong>di</strong> esecuzione<br />

integer/FP/SIMD.<br />

Il risultato dell’esecuzione del<strong>la</strong> µ-op è scritto dall’unità <strong>di</strong> esecuzione in<strong>di</strong>etro<br />

nei registri, o forwardato attraverso una rete <strong>di</strong> bypass ad un’altra µ-op “in<br />

volo” che richiede il risultato. La microarchitettura Nehalem, può supportare il


172 Capitolo 5<br />

“write back” con un throughput <strong>di</strong> una scrittura su registro per ciclo per ogni<br />

porta. La rete <strong>di</strong> bypass consiste <strong>di</strong> 3 spazi integer/FP/SIMD. Il forwar<strong>di</strong>ng del<br />

risultato nello stesso spazio <strong>di</strong> bypass, da una µ-op ad un’altra viene portata a<br />

termine efficientemente in hardware senza ritardo. Il forwar<strong>di</strong>ng tra spazi <strong>di</strong><br />

bypass <strong>di</strong>fferenti è invece soggetto ad un ritardo illustrato in Figura 5.30.<br />

Figura 5.30- Bypass De<strong>la</strong>y tra µ-ops espresso in cicli [24]<br />

La illustra le caratteristiche principali delle issue port e ed i tempi <strong>di</strong> <strong>la</strong>tenza e<br />

throughput delle unità <strong>di</strong> esecuzione per le operazioni più comuni


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 173<br />

Figura 5.31 - Issue Ports del<strong>la</strong> microarchietettura Nehalem [24]<br />

5.4.2 Processori Supersca<strong>la</strong>ri<br />

Il primo esempio <strong>di</strong> applicazione supersca<strong>la</strong>re nei <strong>processori</strong> <strong>Intel</strong> ® si ha con il<br />

Pentium, nel quale viene introdotta una seconda execution pipeline (come<br />

illustrato al paragrafo 5.4.1).


174 Capitolo 5<br />

Nei <strong>processori</strong> del<strong>la</strong> famiglia P6, l’architettura supersca<strong>la</strong>re viene migliorata<br />

rendendo<strong>la</strong> a 3 vie: questo significa che me<strong>di</strong>amente vengono deco<strong>di</strong>ficate,<br />

inviate alle unità <strong>di</strong> esecuzione ed eseguite 3 istruzioni per ciclo <strong>di</strong> clock. Per<br />

poter far questo, l’unità <strong>di</strong> esecuzione ha a <strong>di</strong>sposizione <strong>di</strong>verse unità funzionali<br />

collegate tra <strong>di</strong> loro attraverso 5 porte come evidenziato nel<strong>la</strong> Figura 5.14 e<br />

nel<strong>la</strong> Figura 5.15. Nel Pentium ® Pro le unità funzionali sono 6, nel Pentium ® 2<br />

sono 11, mentre nel Pentium ® 3 sono 12.<br />

Nel<strong>la</strong> microarchitettura NetBurst, il trace cache può consegnare all’execution<br />

core fino a 3 µ-ops per ciclo <strong>di</strong> clock. Le unità <strong>di</strong> esecuzione sono ora 7 e<br />

risultano accessibili attraverso 4 porte (Figura 5.22) .<br />

Con <strong>la</strong> microarchitettura Core si par<strong>la</strong> del<strong>la</strong> tecnologia “<strong>Intel</strong> ® Wide Dynamic<br />

Execution”, <strong>la</strong> quale permette a ciascun processor core <strong>di</strong> caricare, consegnare<br />

ed eseguire con una alta <strong>la</strong>rghezza <strong>di</strong> banda, supportando il retirement fino a 4<br />

istruzioni per ciclo.<br />

5.4.3 Pre<strong>di</strong>zione <strong>dei</strong> salti<br />

Con l’introduzione delle pipeline e delle architetture supersca<strong>la</strong>ri <strong>di</strong>venta<br />

in<strong>di</strong>spensabile implementare un sistema <strong>di</strong> pre<strong>di</strong>zione <strong>dei</strong> salti.<br />

486<br />

Nel 486, primo CPU <strong>Intel</strong> ® con pipeline, <strong>la</strong> gestione <strong>dei</strong> salti è elementare: il<br />

salto vene sempre considerato come “non preso”. Il salto viene in<strong>di</strong>viduato<br />

nello sta<strong>di</strong>o EX del<strong>la</strong> pipeline (paragrafo 5.4.1). Questo comporta sempre <strong>la</strong>


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 175<br />

per<strong>di</strong>ta <strong>di</strong> 2 cicli ogni volta che viene mo<strong>di</strong>ficato il Program Counter, in quanto<br />

il contenuto <strong>di</strong> D1 e D2 deve essere rimpiazzato.<br />

PENTIUM<br />

Il processore Pentium ® <strong>di</strong>spone <strong>di</strong> un algoritmo <strong>di</strong> pre<strong>di</strong>zione <strong>di</strong>namico, che<br />

viene implementato con il “branch target buffer” (BTB), per prevedere possibili<br />

ramificazioni <strong>di</strong> programma.<br />

II BTB può essere visto come una picco<strong>la</strong> cache nel<strong>la</strong> quale ogni voce è<br />

rappresentata dall'in<strong>di</strong>rizzo <strong>di</strong> programma dell'istruzione <strong>di</strong> <strong>di</strong>ramazione, e da un<br />

in<strong>di</strong>rizzo target subor<strong>di</strong>nato. Bit ad<strong>di</strong>zionali, chiamati “History bit”, vengono<br />

impiegati per definire se un loop è "preso" o "non preso", al fine <strong>di</strong> ottimizzare<br />

il flusso del programma in caso <strong>di</strong> esecuzioni ripetute. Ciò permette <strong>di</strong> evitare<br />

interruzioni <strong>di</strong> pipeline a causa <strong>di</strong> prefetch <strong>di</strong> co<strong>di</strong>ce (Figura 5.32). Come già<br />

accennato, il BTB è strettamente accoppiato con i preferch buffers del primo<br />

sta<strong>di</strong>o del<strong>la</strong> pipeline.<br />

I loop possono essere eseguiti in parallelo con un'altra istruzione integer. Se <strong>la</strong><br />

previsione sul<strong>la</strong> ramificazione si rive<strong>la</strong> non corretta, le pipelines subiscono un<br />

flush completo, seguito dal prelevamento <strong>di</strong> un'istruzione. Se <strong>la</strong> previsione non<br />

corretta riguarda un loop non con<strong>di</strong>zionato sono necessari tre cicli ad<strong>di</strong>zionali,<br />

come anche nel caso <strong>di</strong> una non corretta previsione <strong>di</strong> loops con<strong>di</strong>zionati nel<strong>la</strong><br />

“u” pipe. Nel<strong>la</strong> “v” pipe occorrono altri 4 cicli.


176 Capitolo 5<br />

Figura 5.32- BTB del Pentium. Se nel<strong>la</strong> fase D1 (instruction decode) del<strong>la</strong> pipeline<br />

viene scoperta una <strong>di</strong>ramazione del programma, l'in<strong>di</strong>rizzo <strong>di</strong> programma<br />

dell'istruzione <strong>di</strong> loop viene usata come riferimento nel BTB, per comunicare <strong>la</strong><br />

destinazione del<strong>la</strong> <strong>di</strong>ramazione e far partire il meccanismo del code prefetch. Se <strong>la</strong><br />

previsione è corretta, <strong>la</strong> pipeline non viene interrotta. In tal modo possono venire<br />

eseguile in un unico ciclo istruzioni <strong>di</strong> loop con<strong>di</strong>zionate e non con<strong>di</strong>zionale, come<br />

anche NEAR procedure calls in parallelo ad esempio con una istruzione integer. [17]<br />

Osserviamo come i salti che sono “non presi”, non vengono inseriti nel BTB<br />

fino a quando <strong>la</strong> previsione non si rileva errata.<br />

Il BTB del Pentium ® è costituito da 256 entry.<br />

P6<br />

Nel<strong>la</strong> famiglia P6, il BTB e <strong>di</strong> 512 entry e archivia <strong>la</strong> storia <strong>dei</strong> salti<br />

precedentemente incontrati e <strong>la</strong> loro destinazione. Quando un salto viene pre-<br />

caricato (fase PF), il BTB invia l’in<strong>di</strong>rizzo <strong>di</strong> destinazione <strong>di</strong>rettamente nel<strong>la</strong><br />

“Instruction Fetch Unit” (IFU). Appena il salto viene eseguito, il BTB è<br />

aggiornato con il nuovo in<strong>di</strong>rizzo <strong>di</strong> destinazione. Usando il “branch target


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 177<br />

buffer” I salti che sono stati precedentemente incontrati vengono così predetti<br />

<strong>di</strong>namicamente.<br />

L’algoritmo <strong>di</strong> pre<strong>di</strong>zione del “branch target buffer” include un sistema <strong>di</strong><br />

“pattern matching” e 4 bit “history bit”. Per esempio un loop costituito da 4<br />

iterazioni si deve concludere con una pre<strong>di</strong>zione del 100%.<br />

I salti che non sono nel BTB, vengono predetti da un meccanismo <strong>di</strong> pre<strong>di</strong>zione<br />

statico basato sui seguenti algoritmi <strong>di</strong> pre<strong>di</strong>zione:<br />

• I salti non con<strong>di</strong>zionati sono predetti “Presi”<br />

• I salti con<strong>di</strong>zionati “backward” sono considerati “Presi”. Questa rego<strong>la</strong><br />

è invertibile per i loops.<br />

• I salti con<strong>di</strong>zionati “forward” sono considerati “Non Presi”.<br />

• I salti in<strong>di</strong>retti sono considerati “Non Presi”<br />

Questi meccanismi <strong>di</strong> pre<strong>di</strong>zione statica soffrono una picco<strong>la</strong> penalità compresa<br />

tra i 5 o 6 cicli (<strong>la</strong> lunghezza del<strong>la</strong> pipeline fino a quel punto).<br />

NETBURST<br />

La estrema profon<strong>di</strong>tà del<strong>la</strong> pipeline del<strong>la</strong> NetBurst necessità una pre<strong>di</strong>zione <strong>dei</strong><br />

salti molto efficiente per non degradare notevolmente le prestazioni.<br />

I sistema <strong>di</strong> pre<strong>di</strong>zione <strong>dei</strong> salti nel<strong>la</strong> microarchitettura <strong>Intel</strong> ® NetBurst pre<strong>di</strong>ce<br />

tutti i salti “near” (con<strong>di</strong>tional calls, uncon<strong>di</strong>tional calls, returns and in<strong>di</strong>rect<br />

branches). Esso non effettua pre<strong>di</strong>zioni per i trasferimenti “far” (far calls, irets<br />

and software interrupts).


178 Capitolo 5<br />

Diversi sono i meccanismi implementati per ottenere una accurata pre<strong>di</strong>zione<br />

<strong>dei</strong> salti e ridurre il costo <strong>dei</strong> salti. Tra queste tecniche ricor<strong>di</strong>amo:<br />

• Pre<strong>di</strong>zione <strong>di</strong>namica del<strong>la</strong> <strong>di</strong>rezione e del<strong>la</strong> destinazione <strong>dei</strong> salti in base<br />

all’in<strong>di</strong>rizzo lineare delle istruzioni, utilizzando il “branch target buffer”<br />

(BTB)<br />

• Se <strong>la</strong> pre<strong>di</strong>zione <strong>di</strong>namica non è <strong>di</strong>sponibile o è invalida, viene<br />

utilizzata una pre<strong>di</strong>zione statica basata sull’Offset del<strong>la</strong> destinazione: un<br />

salto “backward” è considerato “Preso”, mentre un salto “forward” è<br />

considerato “Non Preso”<br />

• Pre<strong>di</strong>zione degli in<strong>di</strong>rizzi <strong>di</strong> ritorno con un “Return Address Stack” <strong>di</strong><br />

16-entry.<br />

• Capacità <strong>di</strong> costruire una traccia delle istruzioni eseguite nel caso <strong>di</strong><br />

salti predetti “Presi” per evitare penalità del salto.<br />

Il BTB e <strong>la</strong> pre<strong>di</strong>zione statica sono rimaste invariate rispetto al<strong>la</strong> generazione<br />

precedente. Gli aspetti innovativi sono invece il “Return Stack” e <strong>la</strong> “Trace<br />

Cache” <strong>di</strong> cui abbiamo già par<strong>la</strong>to a pagina 116 nel paragrafo re<strong>la</strong>tivo al<strong>la</strong><br />

specializzazione del<strong>la</strong> cache a pagina 158 illustrando <strong>la</strong> pipeline NetBurst.<br />

I ritorni sono sempre considerate presi, ma quando una procedura viene<br />

richiamata da <strong>di</strong>versi posti, una singo<strong>la</strong> pre<strong>di</strong>zione delle destinazioni è<br />

insufficiente.<br />

Il Pentium ® 4 prevede un Return Stack che può pre<strong>di</strong>re l’in<strong>di</strong>rizzo <strong>di</strong> una serie <strong>di</strong><br />

chiamate alle procedure. Questo incrementa i benefici nello svolgimento <strong>di</strong> cicli<br />

contenenti una serie <strong>di</strong> chiamate alle funzioni, nonché riduce <strong>la</strong> necessità <strong>di</strong>


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 179<br />

utilizzare procedure inline, dal momento che vengono ridotti i ritar<strong>di</strong> dovuti alle<br />

chiamate alle procedure.<br />

CORE<br />

Dal<strong>la</strong> tecnologia Core, viene i salti sono predetti da una unità chiamata “Branch<br />

Pre<strong>di</strong>ction Unit” (BTU).<br />

Il BTU contiene le seguenti caratteristiche:<br />

• Return Stack Buffer (RSB) <strong>di</strong> 16-entry per <strong>la</strong> accurata pre<strong>di</strong>zione delle<br />

istruzioni RET<br />

• Front end queuing of BPU lookups. Il BPU fa pre<strong>di</strong>zioni <strong>di</strong> salti per<br />

32Byte al<strong>la</strong> volta, raddoppiando <strong>la</strong> <strong>la</strong>rghezza del motore <strong>di</strong> fetch.<br />

Il BPU garantisce che i salti “presi” siano predetti senza penalità.<br />

Questo deve essere tenuto in considerazione nel<strong>la</strong> fase <strong>di</strong> stesura del<br />

software<br />

Le pre<strong>di</strong>zioni che vengono effettuate dal BTU sono le seguenti:<br />

• Direct Calls and Jumps. Le Destinazioni sono lette come un “Target<br />

Array” senza guardare se <strong>la</strong> pre<strong>di</strong>zione è “Presa” o “Non Presa”.<br />

• In<strong>di</strong>rect Calls and Jumps. Queste possono essere entrambe predette<br />

come una destinazione unica o avere più destinazioni in accordo con i<br />

modelli <strong>di</strong> programma recenti.<br />

• Con<strong>di</strong>tional branches. Pre<strong>di</strong>ce <strong>la</strong> destinazione del salto e se deve o no<br />

essere preso


180 Capitolo 5<br />

NEHALEM<br />

La pre<strong>di</strong>zione <strong>dei</strong> salti in questa microarchitettura viene gestita in <strong>di</strong>versi mo<strong>di</strong>.<br />

Il Branch target buffer è stato migliorato perfezionando l’accuratezza delle<br />

pre<strong>di</strong>zioni.<br />

La ridenominazione è supportata con il “return Stack Buffer” per ridurre I<br />

mispre<strong>di</strong>ction delle istruzioni <strong>di</strong> ritorno.<br />

Inoltre il miglioramento dell’hardware perfeziona <strong>la</strong> gestione delle errate<br />

pre<strong>di</strong>zioni <strong>dei</strong> salti facilitando il recupero delle risorse in modo che il front end<br />

non debba aspettare <strong>di</strong> deco<strong>di</strong>ficare le istruzioni.<br />

5.4.4 VLIW e Tecniche Pre<strong>di</strong>cative<br />

<strong>Intel</strong> ® non ha introdotto queste tecniche nei <strong>processori</strong> desktop e mobile,<br />

applicandole invece in un progetto specifico per applicazioni server sviluppato<br />

insieme ad Hewlett-Packard ® ed alcune università (come quel<strong>la</strong> dell’Illinois).<br />

I concetti <strong>di</strong> base che sono al<strong>la</strong> base <strong>di</strong> questa architettura possono essere così<br />

sintetizzati:<br />

• Parallelismo a livello istruzione (ILP) che viene esplicitato nelle<br />

istruzioni macchina, piuttosto che essere determinato run-time dal<br />

processore;<br />

• Very long instruction words (VLIW) che contengono gruppi <strong>di</strong> tre<br />

istruzioni like-RISC;<br />

• Branch pre<strong>di</strong>cation nelle stesse istruzioni macchina, piuttosto che<br />

pre<strong>di</strong>zione <strong>dei</strong> salti;


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 181<br />

• Specu<strong>la</strong>tive loa<strong>di</strong>ng <strong>dei</strong> dati e delle istruzioni.<br />

<strong>Intel</strong> ® ed HP ® hanno attribuito a questa combinazione <strong>di</strong> concetti l’acronimo<br />

EPIC (Explicity Parallel Instruction Computing).<br />

L’applicazione <strong>di</strong> questi concetti comporta una importanza fondamentale del<br />

compi<strong>la</strong>tore nei riguar<strong>di</strong> delle prestazioni del<strong>la</strong> macchina.<br />

Il compi<strong>la</strong>tore è quin<strong>di</strong> parte integrante <strong>di</strong> una CPU con approccio EPIC. Le<br />

prestazioni <strong>di</strong>pendono <strong>di</strong>rettamente dal<strong>la</strong> qualità delle informazioni fornite dal<br />

compi<strong>la</strong>tore. In accordo con l’approccio RISC, <strong>la</strong> complessità si sposta<br />

dall’hardware al software.<br />

Inoltre l’architettura EPIC, per migliorare le prestazioni, aggiunge molti registri<br />

(<strong>di</strong>verse centinaia) per evitare <strong>di</strong> implementare l’unità <strong>di</strong> ridenominazione<br />

<strong>di</strong>namica <strong>dei</strong> registri e delle istruzioni pre<strong>di</strong>cative per evitare lo svuotamento<br />

delle pipeline.<br />

Il primo prodotto <strong>di</strong> questa architettura è stato l’Itanium ® , un puro esercizio <strong>di</strong><br />

stile che in realtà non è stato mai immesso sul mercato a causa delle sue scarse<br />

prestazioni, mentre negli ultimi anni è stato messo in produzione l’Itanium ® 2.<br />

Figura 5.33 - Loghi <strong>dei</strong> <strong>processori</strong> <strong>Intel</strong>® Itanium® ed Itanium®2


182 Capitolo 5<br />

5.4.5 Multithrea<strong>di</strong>ng<br />

Il multithrea<strong>di</strong>ng è stato introdotto dal<strong>la</strong> <strong>Intel</strong> ® nei <strong>processori</strong> Xeon già nel<br />

2002, e successivamente nel Pentium ® 4 nel<strong>la</strong> versione a 3,06 GHz con il nome<br />

<strong>di</strong> HyperThrea<strong>di</strong>ng. Il nome è altisonante, ma in realtà viene supportata<br />

l’esecuzione <strong>di</strong> due thread in modalità Simultaneous Multi-Threa<strong>di</strong>ng.<br />

La tecnologia HyperThrea<strong>di</strong>ng fa sì che un singolo processore fisico venga visto<br />

come un multiprocessore logico. Per ogni processore logico c’è uno copia dello<br />

stato architetturale e questi <strong>processori</strong> con<strong>di</strong>vidono un singolo set <strong>di</strong> risorse<br />

fisiche <strong>di</strong> esecuzione. Da un punto <strong>di</strong> vista software o architetturale questo<br />

significa che il sistema operativo ed i programmi possono schedu<strong>la</strong>re processi o<br />

threads a ciascun processore logico come se fossero i <strong>processori</strong> fisici <strong>di</strong> un<br />

sistema multiprocessore in cui le CPU con<strong>di</strong>vidono cache e RAM. Dal punto <strong>di</strong><br />

vista microarchitetturale significa che le istruzioni <strong>di</strong> ciascun processore logico<br />

verranno eseguite simultaneamente su delle risorse <strong>di</strong> esecuzione con<strong>di</strong>vise;<br />

questo può comportare un miglioramento dell’utilizzo delle risorse del<br />

processore.<br />

La tecnologia HyperThrea<strong>di</strong>ng implementata sul<strong>la</strong> microarchitettura NetBurst<br />

ha due <strong>processori</strong> logici per ogni processore fisico. La Figura 5.34 mostra uno<br />

schema concettuale delle risorse <strong>di</strong> un processore con tecnologia<br />

HyperThrea<strong>di</strong>ng.


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 183<br />

Figura 5.34 - Due copie dell' "Architectural State" consentono ai <strong>processori</strong> con<br />

tecnologia HyperThrea<strong>di</strong>ng <strong>di</strong> essere visti come 2 <strong>processori</strong> logici [25].<br />

Ogni processore logico contiene un set completo dello stato architetturale.<br />

Lo stato architetturale consiste <strong>di</strong> registri, inclusi i registri general-purpose,<br />

registri <strong>di</strong> controllo, registri per lo stato macchine e l’advanced programmable<br />

interrupt controller (APIC). Da un punto <strong>di</strong> vista software duplicare lo stato<br />

architetturale fa sì che ogni processore fisico appaia come due <strong>processori</strong>. Ogni<br />

processore logico possiede un interrupt controller, o APIC, in modo tale che le<br />

richieste <strong>di</strong> interruzione siano inviate al processore logico opportuno.<br />

La tecnologia HyperThrea<strong>di</strong>ng è pienamente compatibile con software e<br />

hardware precedenti, tuttavia per ottenere il massimo vantaggio sono necessarie<br />

ottimizzazioni. Sistemi operativi come Microsoft ® Windows ® XP e Vista ® sono<br />

già ottimizzati per l’utilizzo <strong>di</strong> questa tecnologia.


184 Capitolo 5<br />

DIMENSIONI E COMPLESSITÀ DEL DIE.<br />

La maggior parte delle tecniche che migliorano le prestazioni <strong>di</strong> un processore<br />

da una generazione al<strong>la</strong> successiva sono complesse e spesso implicano un<br />

incremento significativo delle <strong>di</strong>mensioni del <strong>di</strong>e e del consumo <strong>di</strong> potenza.<br />

L’incremento delle prestazioni apportate da tali tecniche non raggiunge mai<br />

un’efficienza del 100%. I limiti del parallelismo del flusso <strong>di</strong> istruzioni, ad<br />

esempio, implica che il raddoppio del numero delle unità <strong>di</strong> esecuzione <strong>di</strong> un<br />

processore non ottenga il raddoppio delle sue prestazioni; similmente il<br />

semplice raddoppio del<strong>la</strong> frequenza <strong>di</strong> clock non raddoppia le prestazioni perché<br />

un certo numero <strong>di</strong> cicli viene perso a causa <strong>dei</strong> branch mispre<strong>di</strong>ctions.<br />

Assumendo lo stesso processo tecnologico, l’area del <strong>di</strong>e del processore<br />

aumenta <strong>di</strong> circa tre volte rispetto all’aumento <strong>di</strong> prestazioni sugli interi.<br />

La tecnologia HyperThrea<strong>di</strong>ng può ottenere un grosso incremento <strong>di</strong> prestazioni<br />

ad un costo minimo in quanto implica un piccolo aumento delle <strong>di</strong>mensioni del<br />

<strong>di</strong>e. I <strong>processori</strong> logici con<strong>di</strong>vidono strettamente tutte le risorse del processore<br />

fisico incluso caches, unità <strong>di</strong> esecuzione, branch pre<strong>di</strong>ctors, logiche <strong>di</strong><br />

controllo e buses. L’aumento delle <strong>di</strong>mensioni del <strong>di</strong>e è dovuto al secondo stato<br />

architetturale, a logica <strong>di</strong> controllo ad<strong>di</strong>zionale e al<strong>la</strong> replica <strong>di</strong> alcune risorse<br />

chiave. Questi elementi occupano però una porzione molto limitata del<strong>la</strong><br />

superficie del processore, come mostra <strong>la</strong> Figura 5.35.


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 185<br />

Figura 5.35 – L’ <strong>Intel</strong> ® Pentium ® 4 e le risorse del processore visibili che vengono<br />

dulicate per supportare <strong>la</strong> tecnologia HyperThrea<strong>di</strong>ng. L’HyperThrea<strong>di</strong>ng richiede <strong>la</strong><br />

duplicazione anche <strong>di</strong> altri elementi come puntatori e logiche <strong>di</strong> controllo, <strong>la</strong> cui<br />

<strong>di</strong>mensione è però troppo picco<strong>la</strong> per essere visualizzata. [25]<br />

Secondo quanto <strong>di</strong>chiarato da <strong>Intel</strong> ® , l’aumento delle <strong>di</strong>mensioni del chip non<br />

superava il 5% [25].<br />

GLI ELEMENTI DUPLICATI<br />

Gli elementi duplicati in<strong>di</strong>cati in Figura 5.35 sono i seguenti:<br />

• La tabel<strong>la</strong> degli alias <strong>dei</strong> registri: associa i registri <strong>architetturali</strong> a quelli<br />

fisici rinominandoli. I registri <strong>architetturali</strong> devono essere tracciati<br />

in<strong>di</strong>pendentemente per ogni processore logico, richiedendo una tabel<strong>la</strong><br />

separata per ogni processore logico.<br />

• Puntatore all’istruzione successiva e <strong>la</strong> logica <strong>di</strong> controllo associata:<br />

permette <strong>di</strong> tracciare in<strong>di</strong>pendentemente l’evoluzione del programma


186 Capitolo 5<br />

per ogni processore logico. Ci sono due sets <strong>di</strong> puntatori logici<br />

all’istruzione successiva; uno al trace cache, il quale serve come cache<br />

<strong>di</strong> istruzione <strong>di</strong> primo livello e memorizza l’istruzioni deco<strong>di</strong>ficate;<br />

l’altro set nel<strong>la</strong> logica <strong>di</strong> deco<strong>di</strong>fica delle istruzioni che viene usato nel<br />

caso <strong>di</strong> trace-cache miss.<br />

• Il “return stack pre<strong>di</strong>ctor”: tiene traccia delle coppie <strong>di</strong> chiamata/ritorni<br />

dalle funzioni.<br />

• “Instruction streaming buffers” e “trace-cache fill buffers”: sono i<br />

buffers <strong>di</strong> front end e devono essere anch’essi duplicati per il prefetch<br />

delle istruzioni.<br />

• “Instruction trans<strong>la</strong>tion look-aside buffer”: <strong>la</strong> scelta <strong>di</strong> duplicare questo<br />

buffer è basata sulle sue ridotte <strong>di</strong>mensioni e sul fatto che risulta più<br />

semplice replicarlo che con<strong>di</strong>viderlo.<br />

• APIC (Advanced programmable Interrupt Controller): per consentire<br />

agli interrupts <strong>di</strong> arrivare in<strong>di</strong>pendentemente ad ogni processore logico.<br />

CONDIVISIONE DELLE RISORSE<br />

Siccome due thread possono usare contemporaneamente <strong>la</strong> CPU, occorre<br />

adottare delle strategie per fare in modo che entrambi i thread possano utilizzare<br />

le varie risorse del<strong>la</strong> CPU.<br />

<strong>Oltre</strong> agli elementi duplicati <strong>di</strong> cui abbiamo par<strong>la</strong>to sopra, <strong>Intel</strong> ® in<strong>di</strong>vidua 3<br />

<strong>di</strong>verse strategie per <strong>la</strong> con<strong>di</strong>visione delle risorse tra due thread.<br />

• Partition: è il partizionamento vero e proprio delle risorse. Alcune<br />

risorse hardware sono partizionate rigidamente tra i due thread. In altre


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 187<br />

parole, ogni thread può usare esattamente <strong>la</strong> metà del<strong>la</strong> risorsa. E’<br />

questo il caso del<strong>la</strong> coda delle microistruzioni (le µ-ops) che attendono<br />

<strong>di</strong> essere instradate alle varie stazioni <strong>di</strong> prenotazione, e del ROB<br />

(chiamata “retirement queue” nel P4). Questa forma <strong>di</strong> partizionamento<br />

può ovviamente generare una sottoutilizzazione delle risorse gestite in<br />

questo modo, nel caso in cui un thread non usi tutta <strong>la</strong> sua parte <strong>di</strong><br />

risorsa, che potrebbe essere sfruttata dall’altro thread.<br />

• Full Sharing: ovvero con<strong>di</strong>visione vera e propria delle risorse. La<br />

risorsa hardware è completamente con<strong>di</strong>visa. Il primo thread che si<br />

impossessa del<strong>la</strong> risorsa <strong>la</strong> usa, e l’altro thread deve attendere il suo<br />

turno. Questa forma <strong>di</strong> gestione delle risorse risolve il problema <strong>di</strong> una<br />

risorsa idle mentre c’è un thread che vorrebbe usar<strong>la</strong>. Ovviamente nasce<br />

il problema opposto: un thread potrebbe venire rallentato dal fatto che<br />

l’altro occupa completamente <strong>la</strong> risorsa. Per questa ragione, nel P4 le<br />

uniche risorse completamente con<strong>di</strong>vise sono quelle presenti in<br />

abbondanza, per cui si ritiene che non si possano verificare problemi <strong>di</strong><br />

“starvation” per un thread, ad esempio le cache lines.<br />

• Threshold: ovvero Con<strong>di</strong>visione control<strong>la</strong>ta delle risorse. In sostanza,<br />

un thread può utilizzare <strong>la</strong> risorsa in modo <strong>di</strong>namico, ma solo fino ad un<br />

certo massimo, in modo che ne rimanga sempre una parte (che può<br />

essere però meno del<strong>la</strong> metà) all’altro thread. Ad esempio, lo scheduler<br />

che invia le µ-ops alle varie stazioni <strong>di</strong> prenotazione è gestito in questo<br />

modo.


188 Capitolo 5<br />

La Figura 5.36 mostra <strong>la</strong> con<strong>di</strong>visione delle risorse nel<strong>la</strong> pipeline del Pentium4.<br />

E’ evidente che <strong>la</strong> con<strong>di</strong>visione <strong>di</strong>namica con limite massimo delle varie risorse<br />

richiede un monitoraggio a run-time <strong>di</strong> tale risorse, e quin<strong>di</strong> dell’hardware<br />

aggiuntivo e dell’overhead computazionale.<br />

Figura 5.36 – In questa vista del<strong>la</strong> execution pipeline del<strong>la</strong> microarchitettura NetBurst,<br />

le aree chiare e scure in<strong>di</strong>cano l’utilizzo delle risorse <strong>di</strong> due threads avviate sui due<br />

<strong>processori</strong> logici [25].<br />

APPLICAZIONE NELLE CPU INTEL ®<br />

Abbiamo già accennato come questa tecnologia sia stata inserita nelle CPU con<br />

microarchitettura NetBurst. <strong>Intel</strong> ® ha abbandonato <strong>la</strong> tecnologia<br />

HyperThrea<strong>di</strong>ng nel passaggio ai <strong>processori</strong> dual core (<strong>la</strong> cui microarchitettura<br />

può essere considerata come una versione aggiornata del<strong>la</strong> microarchitettura P6,<br />

che non supporta il multithrea<strong>di</strong>ng). È invece stato reintrodotto nel<strong>la</strong> CPU del<strong>la</strong><br />

famiglia Nehalem.


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 189<br />

5.4.6 Multicore<br />

<strong>Intel</strong> ® ha introdotto <strong>la</strong> tecnologia Multicore già con <strong>la</strong> microarchitettura<br />

NetBurst (Pentium ® D), utilizzando due core su <strong>di</strong> un singolo <strong>di</strong>e.<br />

Il primo progetto <strong>Intel</strong> ® ad avvantaggiarsi del<strong>la</strong> tecnologia dual core ma su <strong>di</strong>e<br />

doppio è stato il Pentium ® D Presler, che però ha avuto successo, nonostante<br />

fosse economico.<br />

Solo con l’avvento del<strong>la</strong> famiglia Core, <strong>Intel</strong> ® ha cominciato ad utilizzare<br />

l’approccio <strong>di</strong>e Monolitico.<br />

Attualmente, nonostante ci siano progetti per architetture a 80 core (che forse<br />

uscirà nel 2011), <strong>Intel</strong> ® ha commercializzato ad oggi so<strong>la</strong>mente <strong>processori</strong> a 2 e<br />

4 core per il settore desktop e mobile, mentre uscirà a breve con un processore<br />

Xeon a 8 core per piattaforme server.<br />

In Figura 5.37 si riportano per completezza gli schemi a blocchi delle unità<br />

funzionali <strong>dei</strong> <strong>processori</strong> appena citati; da tali schemi è possibile evincere quali<br />

unità sono con<strong>di</strong>vise e quali replicate per ogni core.


190 Capitolo 5<br />

Figura 5.37 – Con<strong>di</strong>visione delle risorse in alcune CPU <strong>Intel</strong> Multicore<br />

5.5 Parallelismo a livello <strong>di</strong> dato<br />

Innanzitutto quando si par<strong>la</strong> <strong>di</strong> parallelismo a livello <strong>di</strong> dato è necessario<br />

definire le <strong>di</strong>mensioni <strong>dei</strong> registri interni e del bus <strong>dei</strong> dati. In partico<strong>la</strong>re, è<br />

doveroso citare il recente passaggio delle architetture <strong>Intel</strong> ® dai 32 ai 64 bit.


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 191<br />

Molti dubbi sono sorti riguardo <strong>la</strong> reale necessità <strong>di</strong> una tale rivoluzione, a tale<br />

riguardo basti pensare a quello che è accaduto anni prima quando si è passati da<br />

16 a 32 bit: pian piano superando alcuni problemi abbiamo vissuto <strong>la</strong><br />

transizione da Windows ® for Workgroup 3.11 a Windows ® 95, fino a giungere<br />

all’attuale Windows ® XP, con notevoli benefici per il mercato degli utilizzatori.<br />

Si noti che già nei tar<strong>di</strong> anni ‘90 sono stati introdotti i primi <strong>processori</strong> RISC a<br />

64 bit, <strong>la</strong> cui applicazione è stata strettamente <strong>di</strong> tipo server, rimanendo perlopiù<br />

sconosciuti al grande pubblico. Questo non è assolutamente un dettaglio da<br />

trascurare, al contrario <strong>la</strong> storia delle CPU ci ha <strong>di</strong>mostrato più volte che <strong>la</strong><br />

completa affermazione <strong>di</strong> un processore su <strong>di</strong> un altro non <strong>di</strong>pende so<strong>la</strong>mente da<br />

parametri tecnologici ma anche dall’economicità del prodotto e dal momento <strong>di</strong><br />

immissione sul mercato (time-to-market): infatti il dominio dell’architettura x86<br />

nel mercato <strong>dei</strong> Personal Computer è dovuta in gran parte ai micro<strong>processori</strong><br />

<strong>Intel</strong> ® 8086 ed 8088, il primo <strong>dei</strong> quali fu immesso sul mercato con un anno e<br />

mezzo <strong>di</strong> anticipo rispetto agli avversari a 16 bit <strong>di</strong> Motoro<strong>la</strong> ® e Zilog ® , mentre<br />

il secondo fu l’unico microprocessore con bus dati esterno a 8 bit a poter<br />

in<strong>di</strong>rizzare fino ad 1 Mbyte <strong>di</strong> memoria ad un prezzo estremamente basso<br />

mantenendo <strong>la</strong> compatibilità con i programmi del fratello maggiore 8086, e<br />

contribuendo così notevolmente al<strong>la</strong> <strong>di</strong>ffusione dell’ISA x86.<br />

E proprio facendo tesoro <strong>di</strong> tali esperienze, il produttore più pronto ad attuare <strong>la</strong><br />

transizione ai 64 bit è stata l’AMD ® che ha introdotto l’Athlon ® 64, che si può<br />

considerare il primo processore a 64 bit per soluzioni <strong>di</strong> tipo desktop.


192 Capitolo 5<br />

I principali vantaggi derivanti da una semplice transizione dell’architettura da<br />

32 a 64 bit sono l’aumento del<strong>la</strong> grandezza <strong>dei</strong> registri, che era stato già adottato<br />

anni ad<strong>di</strong>etro tramite le estensioni SIMD, e l’aumento del<strong>la</strong> memoria principale<br />

in<strong>di</strong>rizzabile che sale dagli attuali 2³² = 4.3 GByte ad un massimo teorico <strong>di</strong> 18<br />

milioni <strong>di</strong> Terabyte. Questo rappresenta un evidente vantaggio soprattutto per i<br />

server che possono per esempio caricare <strong>di</strong>rettamente in<br />

memoria interi database <strong>di</strong> <strong>di</strong>mensioni superiori ai 4.3 GByte (anche se i<br />

<strong>processori</strong> <strong>Intel</strong> ® Xeon © a 32 bit erano già riusciti ad in<strong>di</strong>rizzare fino a 64 GByte<br />

grazie a partico<strong>la</strong>ri tecniche), ma potrà tornare molto utile in un futuro non<br />

molto lontano (3 o 4 anni) anche nelle applicazioni multime<strong>di</strong>ali per sistemi<br />

desktop.<br />

<strong>Intel</strong> ® ha inoltre adottato come in altri casi una strategia <strong>di</strong> compatibilità col<br />

passato. Me<strong>di</strong>ante <strong>la</strong> tecnologia EM64T consente ai <strong>processori</strong> (quali il<br />

Pentium ® D e i multicore) <strong>di</strong> <strong>la</strong>vorare sia a 32 che a 64 bit. So<strong>la</strong>mente <strong>la</strong><br />

famiglia Itanium, invece, nasce esclusivamente a 64 bit.<br />

5.6 Nuove tecnologie per le cache <strong>di</strong> <strong>Intel</strong> ®<br />

<strong>Intel</strong> ® ha compiuto passi avanti nel<strong>la</strong> ricerca e sviluppo <strong>di</strong> una nuova tecnologia<br />

che consentirebbe <strong>la</strong> produzione <strong>di</strong> memorie cache alternative rispetto a quelle<br />

comunemente utilizzate oggi. Si tratta delle memorie cosiddette Floating Body<br />

Cell, alle quali il colosso californiano sta <strong>la</strong>vorando già dal 2006.


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 193<br />

Le memorie cache vengono utilizzate per conservare dati ai quali è necessario<br />

accedere frequentemente, in modo tale che questi dati possano essere resi<br />

<strong>di</strong>sponibili più velocemente rispetto ad uno stoccaggio su hard <strong>di</strong>sk o sul<strong>la</strong><br />

memoria <strong>di</strong> sistema. E’ chiaro che una maggiore densità <strong>di</strong> memoria per le<br />

cache comporterebbe interessanti vantaggi.<br />

Le celle delle memorie cache, che <strong>di</strong> fatto sono memorie SRAM, vengono<br />

realizzate con sei transistor e sono in grado <strong>di</strong> conservare un bit <strong>di</strong><br />

informazione. Obiettivo è <strong>di</strong> riuscire ad arrivare all’impiego <strong>di</strong> un solo transistor<br />

per un bit <strong>di</strong> informazione. Questo tipo <strong>di</strong> struttura è giù utilizzato nelle normali<br />

memorie DRAM, le cui celle sono costituite da un transistor, che tuttavia<br />

risultano troppo lente per un impiego come memorie cache.<br />

Il principio sul quale si basano le memorie <strong>di</strong> tipo Floating Body Cell prevede <strong>la</strong><br />

conservazione <strong>di</strong> una carica elettrica in una cel<strong>la</strong> <strong>di</strong> memoria interposta tra uno<br />

strato <strong>di</strong> Silicon-On-Insu<strong>la</strong>tor e un gate <strong>di</strong> un transistor. Grazie all’affinamento<br />

<strong>dei</strong> processi produttivi, <strong>Intel</strong> ® ha potuto realizzare un prototipo utilizzando un<br />

gate metallico da 45 nanometri e posizionando <strong>la</strong> cel<strong>la</strong> <strong>di</strong> memoria tra esso e un<br />

substrato SOI (silicon-on-insu<strong>la</strong>tor) <strong>di</strong> appena 22 nanometri <strong>di</strong> spessore.<br />

Le memorie FBC risultano comunque meno veloci rispetto alle memorie SRAM<br />

ma sono meno costose da produrre. La possibilità <strong>di</strong> utilizzare un solo transistor<br />

per ogni bit <strong>di</strong> informazione consente inoltre <strong>di</strong> poter raggiungere elevate


194 Capitolo 5<br />

densità <strong>di</strong> memoria permettendo in un futuro <strong>di</strong> realizzare <strong>processori</strong> con elevati<br />

quantitativi <strong>di</strong> memoria cache integrata.<br />

<strong>Intel</strong> ® non ha tuttavia rive<strong>la</strong>to partico<strong>la</strong>ri prospettive <strong>di</strong> impiego per questo<br />

nuovo tipo <strong>di</strong> memorie, precisando che prima <strong>di</strong> poter giungere al<strong>la</strong> fase <strong>di</strong><br />

implementazione ed integrazione in un chip è necessario dover fronteggiare una<br />

serie <strong>di</strong> problemi: attualmente infatti le più <strong>di</strong>ffuse implementazioni SOI<br />

prevedono un substrato dallo spessore maggiore rispetto a quello utilizzato per<br />

<strong>la</strong> realizzazione del prototipo <strong>di</strong> <strong>Intel</strong> ® e per i processi produttivi attuali non è<br />

ancora possibile realizzare un unico chip con substrati <strong>di</strong> spessori <strong>di</strong>fferenti.<br />

5.7 Set <strong>di</strong> Istruzioni<br />

5.7.1 IA-32: CISC o RISC?<br />

Le basi dell’architettura IA-32 sono state poste nel 1978 con il processore 8086<br />

a 16-bit, macchina CISC tra<strong>di</strong>zionale, che si impose subito sul mercato;<br />

sull’onda del successo <strong>di</strong> questo processore nacquero altri <strong>processori</strong> a 16-bit,<br />

come l’8088 e l’80286, che mantennero <strong>la</strong> compatibilità dell’ISA x86. Ma il<br />

primo processore ad architettura IA-32 è stato sicuramente l’80386 che ha<br />

segnato anche <strong>la</strong> grande transizione dai 16 ai 32 bit. Già nell’80486 si sono<br />

cominciate a vedere le prime influenze <strong>di</strong> progettazione <strong>di</strong> tipo RISC con<br />

l’introduzione del concetto <strong>di</strong> pipeline (una pipeline a cinque sta<strong>di</strong>: prefetch,<br />

deco<strong>di</strong>fica, generazione dell’in<strong>di</strong>rizzo, esecuzione, Write-Back), ma ancora<br />

senza alcun elemento supersca<strong>la</strong>re. Infatti, è stato con l’introduzione del


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 195<br />

Pentium ® che si è introdotto il concetto <strong>di</strong> supersca<strong>la</strong>rità con l’adozione <strong>di</strong> due<br />

unità <strong>di</strong> esecuzione ad interi poste sulle due pipeline <strong>di</strong>stinte u e v, capaci <strong>di</strong><br />

eseguire insieme due istruzioni per clock.<br />

Un ulteriore evoluzione verso una tecnologia interme<strong>di</strong>a tra CISC e RISC,<br />

possiamo <strong>di</strong>re si sia avuta con l’uscita del Pentium ® 4, ovvero con <strong>la</strong><br />

microarchitettura NetBurst ® . Le operazioni compiute dal Pentium ® 4 possono<br />

essere riassunte così [26]:<br />

• Il processore carica le istruzioni <strong>di</strong> lunghezza variabile (fino ad un<br />

massimo <strong>di</strong> una word pari a 32 bit) dal<strong>la</strong> memoria nell’or<strong>di</strong>ne previsto<br />

dal programma;<br />

• Ogni istruzione del Pentium ® 4 viene tradotta in una o più istruzioni<br />

like-RISC <strong>di</strong> lunghezza prefissata, chiamate µ-ops (un’istruzione<br />

contiene da 1 a 4 µ-ops <strong>di</strong> tipo RISC, ognuna delle quali è lunga 118<br />

bit);<br />

• Il processore esegue le µ-ops in una pipeline supersca<strong>la</strong>re grazie ad un<br />

algoritmo <strong>di</strong> esecuzione fuori or<strong>di</strong>ne;<br />

• Al<strong>la</strong> fine viene restituito il risultato <strong>di</strong> ogni µ-ops al corrispondente<br />

registro nell’or<strong>di</strong>ne originale del programma.<br />

In effetti, l’architettura del Pentium ® 4 è composta da una parte esterna <strong>di</strong> tipo<br />

CISC con un cuore <strong>di</strong> tipo RISC. Le µ-ops passano attraverso una pipeline<br />

lunga ben 31 sta<strong>di</strong> (nel Pentium ® 4 con core Prescott); in alcuni casi, le µ-ops<br />

richiedono più sta<strong>di</strong> <strong>di</strong> esecuzione, rendendo ancora più lunga <strong>la</strong> pipeline.


196 Capitolo 5<br />

Perciò possiamo in<strong>di</strong>care questo tipo <strong>di</strong> filosofia <strong>di</strong> progettazione con il termine<br />

Post-CISC[15].<br />

Figura 5.38 – Approccio Post-CISC [15]<br />

Questa soluzione ha permesso <strong>di</strong> sfruttare <strong>la</strong> bontà dell’approccio RISC pur<br />

mantenendo <strong>la</strong> “back-compatibility” con i <strong>processori</strong> precedenti e decretando<br />

così il successo <strong>di</strong> questa architettura.<br />

5.7.2 Tecnologia SIMD<br />

Sempre per quanto riguarda <strong>la</strong> computazione in parallelo, ci si è accorti subito<br />

che l’Instruction set x86 risultava inadatto a questo scopo, ma dovendo essere<br />

mantenuto per ragioni <strong>di</strong> compatibilità all’in<strong>di</strong>etro si è proceduti ad un<br />

progressivo aumento <strong>di</strong> istruzioni e <strong>di</strong> registri specializzati (pratica in auge<br />

anche negli attuali <strong>processori</strong> RISC), in modo da consentire <strong>di</strong> eseguire più


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 197<br />

computazioni con una singo<strong>la</strong> istruzione. Il termine Single Instruction Multiple<br />

Data (SIMD), che significa proprio istruzioni che permettono <strong>di</strong> manipo<strong>la</strong>re più<br />

dati con un singolo comando, sta proprio ad in<strong>di</strong>care tutte quelle espansioni<br />

(MMX, SSE, SSE2, etc) che si sono succedute nel tempo.<br />

Le SIMD si propongono l’obiettivo <strong>di</strong> aumentare le prestazioni <strong>di</strong> applicazioni<br />

grafiche 3D, <strong>di</strong> riconoscimento vocale, <strong>di</strong> e<strong>di</strong>ting video e multime<strong>di</strong>ali che<br />

abbiano come caratteristica:<br />

• parallelismo intrinseco;<br />

• modelli <strong>di</strong> accesso in memoria rego<strong>la</strong>ri e ricorrenti;<br />

• operazioni ricorrenti sui dati;<br />

• flusso <strong>di</strong> controllo senza <strong>di</strong>pendenze <strong>dei</strong> dati.<br />

Figura 5.39 - Estensioni dell'Instruction set nei <strong>processori</strong> <strong>Intel</strong> ® [27]<br />

Di seguito sono brevemente illustrate le sei generazioni <strong>di</strong> istruzioni SIMD<br />

implementate da <strong>Intel</strong> ® nei suoi <strong>processori</strong>:<br />

MMX<br />

Fu introdotta per <strong>la</strong> prima volta in una versione del Pentium, chiamato appunto<br />

Pentium ® MMX. Prevedeva l’utilizzo degli 8 registri Floating-Point da 80 bit,<br />

come registri a 64 bit da utilizzare con le unità integer, chiamandoli registri


198 Capitolo 5<br />

MMX, e introduceva le istruzioni per potere eseguire operazioni su word e<br />

double word.<br />

Le istruzioni MMX tuttavia fallirono l’obiettivo <strong>di</strong> portare i benefici del<br />

para<strong>di</strong>gma SIMD nei comuni personal computer. E questo si era avuto per due<br />

motivazioni principali: lo scarso supporto fornito da <strong>Intel</strong> ® agli sviluppatori e <strong>la</strong><br />

mancanza <strong>di</strong> istruzioni utilizzabili nell’emergente mondo del<strong>la</strong> grafica 3D. Le<br />

istruzioni MMX manipo<strong>la</strong>no numeri interi e quin<strong>di</strong> non sono in grado <strong>di</strong> gestire<br />

le trasformazioni geometriche <strong>dei</strong> videogiochi perché in questo compito sono<br />

richieste operazioni floating point; inoltre l’utilità <strong>di</strong> un set <strong>di</strong> istruzioni capace<br />

<strong>di</strong> accelerare tali calcoli si è resa visibile in maniera pesante con l’affermazione<br />

<strong>di</strong> API de<strong>di</strong>cate al<strong>la</strong> gestione del 3D quali le Direct 3D e OpenGL, capaci <strong>di</strong><br />

astrarre lo sviluppatore dal co<strong>di</strong>ce ottimizzato vero e proprio[28].<br />

SSE<br />

Col Pentium ® III viene fatta una estensione del set <strong>di</strong> istruzioni chiamato<br />

Internet SSE (Internet Streaming SIMD Extension) o, più semplicemente SSE;<br />

questo set metteva a <strong>di</strong>sposizione 8 registri reali a 128 bit chiamati XMM e le<br />

re<strong>la</strong>tive istruzioni per compiere operazioni in virgo<strong>la</strong> mobile a singo<strong>la</strong><br />

precisione. Tra le istruzioni SSE, ne esistono anche 4 per il data prefetch.


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 199<br />

Figura 5.40 - MMX ed SSE a confronto[29]<br />

L’obbiettivo che i progettisti <strong>Intel</strong> ® si erano proposti, era <strong>di</strong> raggiungere un<br />

incremento delle prestazioni floating point tra il 70% e il 100%, ritenuto<br />

sufficiente a rendere percettibile <strong>la</strong> <strong>di</strong>fferenza e quin<strong>di</strong> competitivo il prodotto,<br />

al minor costo possibile in termini <strong>di</strong> incremento del<strong>la</strong> complessità e aumento<br />

delle <strong>di</strong>mensioni del <strong>di</strong>e. Nel contempo si decise <strong>di</strong> estendere <strong>la</strong> tecnologia<br />

MMX (quale ad esempio istruzioni per facilitare le co<strong>di</strong>fiche in tempo reale <strong>di</strong><br />

tipo MPEG-2) e <strong>di</strong> introdurre istruzioni per mascherare <strong>la</strong> <strong>la</strong>tenza che deriva<br />

dalle notevoli <strong>di</strong>mensioni, in termini <strong>di</strong> memoria, <strong>dei</strong> dati implicati in<br />

applicazioni video. Il termine Streaming si riferisce appunto al<strong>la</strong> presenza <strong>di</strong><br />

istruzioni che permettono il prefetch <strong>di</strong> dati simultaneamente all’e<strong>la</strong>borazione <strong>di</strong><br />

altri già <strong>di</strong>sponibili velocizzando il flusso (stream) <strong>dei</strong> dati in ingresso e in<br />

uscita dal processore nascondendo nel tempo <strong>di</strong> esecuzione <strong>la</strong> <strong>la</strong>tenza del fetch.<br />

Una delle scelte basi<strong>la</strong>ri nel<strong>la</strong> definizione <strong>di</strong> un’architettura SIMD consiste nel<br />

definire su quanti dati contemporaneamente si vuole operare in modo da


200 Capitolo 5<br />

raggrupparli in un vettore <strong>di</strong> <strong>di</strong>mensioni adeguate, che costituir`a il nuovo tipo<br />

<strong>di</strong> dato cui faranno riferimento le istruzioni SIMD.<br />

Il team <strong>di</strong> sviluppatori <strong>di</strong> <strong>Intel</strong> ® ritenne che <strong>la</strong> computazione paralle<strong>la</strong> <strong>di</strong> 4<br />

floating point a singo<strong>la</strong> precisione (32 bit) e quin<strong>di</strong> <strong>di</strong> un data-type SSE da 128<br />

bit consentisse un raddoppio complessivo delle performance senza aggiungere<br />

eccessiva complessità essendo tendenzialmente ottenibile con un doppio ciclo<br />

del<strong>la</strong> esistente architettura a 64 bit. La scelta <strong>di</strong> operare su 2 floating point non<br />

avrebbe consentito <strong>di</strong> ottenere paragonabili prestazioni mentre l’adozione <strong>di</strong> un<br />

datapath <strong>di</strong> 256 bit (8 FP da 32 bit) avrebbe determinato un impatto maggiore in<br />

termini <strong>di</strong> complessità. Mentre i 128 bit possono essere separati in 2 istruzioni<br />

da 64 bit che possono essere eseguite, con 256 bit si sarebbe dovuto, per<br />

mantenere lo stesso throughput, raddoppiare <strong>la</strong> <strong>la</strong>rghezza delle unità <strong>di</strong><br />

esecuzione e quin<strong>di</strong> <strong>la</strong> banda <strong>di</strong> memoria per alimentarle. Stabilito il datapath <strong>di</strong><br />

128 bit si poneva <strong>la</strong> domanda se implementare i registri a 128 bit nei registri<br />

MMX/x87 esistenti oppure definire un nuovo stato con registri appositi. La<br />

prima scelta, analoga a quel<strong>la</strong> attuata con l’estensione al<strong>la</strong> tecnologia MMX,<br />

avrebbe comportato il vantaggio del<strong>la</strong> piena compatibilità con il sistema<br />

operativo ma lo svantaggio <strong>di</strong> dover con<strong>di</strong>videre i registri, già penalizzanti,<br />

del<strong>la</strong> architettura IA-32. La seconda scelta avrebbe comportato il problema <strong>di</strong><br />

dover adattare i sistemi operativi, problema poco sentito da <strong>Intel</strong> ® data <strong>la</strong> sua<br />

forza contrattuale, ma avrebbe avuto il vantaggio <strong>di</strong> facilitare i programmatori e<br />

<strong>la</strong> possibilità <strong>di</strong> eseguire contemporaneamente istruzioni MMX, x87 o SIMD-<br />

FP. I progettisti <strong>Intel</strong> ® optarono per aggiungere un nuovo stato architetturale,


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 201<br />

per <strong>la</strong> prima volta dai tempi dell’aggiunta <strong>di</strong> quello x87 ai tempi del i386 nel<br />

1985, con <strong>la</strong> definizione <strong>di</strong> 8 nuovi registri da 128 bit (chiamati registri XMM),<br />

cosa che non era stata fatta con l’introduzione delle istruzioni MMX che<br />

operavano sugli stesi registri fisici del<strong>la</strong> Floating Point Unit. [28]<br />

SSE2<br />

Introdotto con il Pentium ® 4, ha permesso <strong>di</strong> compiere operazioni in virgo<strong>la</strong><br />

mobile a doppia precisione, nonché moltiplicazioni tra interi a 32bit (importanti<br />

per il processing au<strong>di</strong>o <strong>di</strong> qualità). L’estensione ha aggiunto altre 144 istruzioni<br />

SIMD che prendono il nome <strong>di</strong> SSE2, che hanno colmato buona parte delle<br />

mancanze presenti in SSE.<br />

SSE3<br />

Nel<strong>la</strong> versione del Pentium ® 4 con core Prescott è arrivata l’ultima estensione<br />

SSE3, che aggiunge altre 13 nuove istruzioni e ne hanno semplificato l’utilizzo.<br />

SUPPLEMENTAL SSE3<br />

Nei <strong>processori</strong> con microarchitettura Core, sono ora <strong>di</strong>sponibili 32 nuove<br />

istruzioni, tra le quali operazioni <strong>di</strong> allineamento e multiply-add, che<br />

permettono un miglioramento delle prestazioni.<br />

SSE4<br />

È <strong>la</strong> più grande estensione del set <strong>di</strong> istruzioni in termini <strong>di</strong> portata e <strong>di</strong> impatto<br />

dal SSE2. Prevede <strong>di</strong>verse “Compiler Vectorization Primitives” per ancora<br />

maggiori prestazioni multime<strong>di</strong>ali, come le nuove ed innovative “string


202 Capitolo 5<br />

processing instructions”. L’esor<strong>di</strong>o <strong>di</strong> questa estensione si è avuto con i<br />

<strong>processori</strong> Penryn. Per lo sviluppo <strong>di</strong> questo progetto, <strong>Intel</strong> ® ha <strong>la</strong>vorato con<br />

<strong>di</strong>versi partner, incluso ISVs (in<strong>di</strong>pendent sofwtare vendors) e OSVs (operating<br />

system vendors), in modo da sviluppare SS4 come un nuovo instruction set<br />

standard.<br />

SSE4 prevede decine <strong>di</strong> nuove istruzioni innovative che possono essere<br />

raggruppate in tre categorie:<br />

• SSE4 Vectorizing Compiler and Me<strong>di</strong>a Accelerators: Aggiunge molte<br />

nuove “compiler vectorization primitives” (operazioni fondamentali a<br />

partire dalle quali si possono costruire quelle più complesse) che<br />

estendono le funzionalità dell’architettura <strong>Intel</strong> ® , consentendo<br />

l’ottimizzazione delle prestazioni e <strong>la</strong> riduzione del<strong>la</strong> potenza utilizzata.<br />

I compi<strong>la</strong>tori che faranno uso <strong>di</strong> queste primitive, saranno in grado <strong>di</strong><br />

garantire questi benefici per un ampio numero <strong>di</strong> applicazioni, incluse<br />

le applicazioni server HPC (high performance computing).<br />

Le nuove primitive includono miglioramenti sulle operazioni intere e<br />

floating point, il supporto per operazioni DWORD e QWORD<br />

pacchettizzate, nuove operazioni a singo<strong>la</strong> precisione FP, operazioni<br />

veloci tra i registri, operazioni in memoria performance-optimized, etc.<br />

Le tipiche applicazioni che traggono beneficio da questa architettura<br />

sono quelle che riguardano l’e<strong>la</strong>borazione delle immagini, <strong>la</strong> grafica,<br />

l’e<strong>la</strong>borazione video, <strong>la</strong> generazione <strong>di</strong> immagini 3D, multime<strong>di</strong>ali,


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 203<br />

giochi, ad alta intensità <strong>di</strong> <strong>la</strong>voro con le memorie le HPC e molte<br />

ancora.<br />

• SSE4 Efficient Accelerated String and Text Processing: sono presenti<br />

nuove istruzioni per l’e<strong>la</strong>borazione <strong>di</strong> stringhe e testo ottimizzate. Tra<br />

queste ricor<strong>di</strong>amo quelle <strong>di</strong> comparazione avanzata <strong>di</strong> pacchetti <strong>di</strong><br />

stringhe, che possono eseguire più operazioni <strong>di</strong> confronto e <strong>di</strong> ricerca<br />

in una singo<strong>la</strong> istruzione. In generale, ciascuna <strong>di</strong> queste nuove<br />

istruzioni ha un ricco set <strong>di</strong> funzionalità innovative sul<strong>la</strong> e<strong>la</strong>borazione<br />

delle stringhe che nelle ISA precedenti si potevano eseguire solo con un<br />

elevato numero <strong>di</strong> istruzioni.<br />

Queste istruzioni permettono un impulso prestazione per una vasta<br />

gamma <strong>di</strong> applicazioni <strong>di</strong> e<strong>la</strong>borazione <strong>dei</strong> dati, <strong>di</strong> ricerca e in genere su<br />

tutte le applicazioni basate su testo. Tra queste ricor<strong>di</strong>amo le<br />

applicazioni che coinvolgono database, ricerche testuali, scansioni<br />

antivirus, librerie <strong>di</strong> string process come ZLIB, Token<br />

parsing/recognizing applications come i compi<strong>la</strong>tori e applicazioni<br />

“state machine oriented”.<br />

SSE4 Application Targeted Accelerators. Esse estendono le capacità<br />

dell’architettura <strong>Intel</strong> ® . Si tratta <strong>di</strong> piccole istruzioni a bassa <strong>la</strong>tenza<br />

destinate all'ottimizzazione <strong>di</strong> specifiche applicazioni; ad esempio vi è<br />

<strong>la</strong> possibilità <strong>di</strong> eseguire una serie <strong>di</strong> operazioni su co<strong>di</strong>ce <strong>di</strong> linguaggi<br />

specifici, come XML, e in generale per manipo<strong>la</strong>re le stringhe <strong>di</strong><br />

caratteri [30]


204 Capitolo 5<br />

Osserviamo infine come l’<strong>Intel</strong> ® sia sempre riuscita ad imporsi sugli altri<br />

costruttori per questo tipo <strong>di</strong> istruzioni, <strong>di</strong>ventando lo standard <strong>di</strong> facto. Un<br />

esempio <strong>la</strong>mpante si è avuto con l’introduzione delle SSE2 in concomitanza con<br />

il 3DNow! <strong>di</strong> AMD ® . La vasta adozione dell’estensione SSE2 presso le<br />

maggiori software house ha costretto l’AMD ® a tornare sui propri passi<br />

ri<strong>di</strong>mensionando le proprie ambizioni espansionistiche e adottando suo<br />

malgrado le estensioni SIMD dell’ <strong>Intel</strong> ® (pagandone le royalty).<br />

5.8 Il risparmio energetico<br />

Come descritto nel paragrafo 2.2, i problemi re<strong>la</strong>tivi al<strong>la</strong> potenza <strong>di</strong>ssipata sono<br />

sempre più importanti. <strong>Intel</strong> ® ha cominciato inizialmente su famiglie apposite<br />

(Mobile) e solo ultimamente ha applicato mo<strong>di</strong>fiche <strong>architetturali</strong> nel<strong>la</strong><br />

progettazione <strong>dei</strong> <strong>la</strong>yout <strong>di</strong> tutti i <strong>processori</strong> per ottenere <strong>la</strong> riduzione del<br />

consumo <strong>di</strong> energia.<br />

La tabel<strong>la</strong> e il grafico seguenti mostrano il TDP <strong>di</strong> alcuni <strong>processori</strong> <strong>Intel</strong> ® per<br />

piattaforme desktop fino al Pentium ® D. Si rimanda al Capitolo 6 le innovazioni<br />

micro<strong>architetturali</strong> che <strong>Intel</strong> ® ha inserito nell’ultima generazione <strong>di</strong> <strong>processori</strong><br />

Nehalem.


Applicazione nei <strong>processori</strong> <strong>Intel</strong>® 205<br />

Clock ⎡MHz<br />

⎤<br />

Serie Clock TDP [W]<br />

TDP ⎢<br />

⎣ W ⎥<br />

⎦<br />

Pentium ® II 233 34,80 6,6954023<br />

Pentium ® II (Deschutes) 266 16,80 15,8333333<br />

Pentium ® II (K<strong>la</strong>math) 266 38,60 6,89119171<br />

Pentium ® II (K<strong>la</strong>math) 300 43,00 6,97674419<br />

Pentium ® II (Deschutes) 400 24,30 16,4609053<br />

Pentium ® II 450 27,10 16,6051661<br />

Pentium ® III 450 25,30 17,7865613<br />

Pentium ® III 500 28,00 17,8571429<br />

Pentium ® III-E 500 13,20 37,8787879<br />

Pentium ® III-(B) 600 34,50 17,3913043<br />

Pentium ® III-E(B) 600 15,80 37,9746835<br />

Pentium ® III 700 18,30 38,2513661<br />

Pentium ® III 733 19,10 38,3769634<br />

Pentium ® III 800 20,10 39,800995<br />

Pentium ® III 850 25,70 33,07393<br />

Pentium ® III 866 26,10 33,1800766<br />

Pentium ® III (SECC2) 933 25,50 36,5882353<br />

Pentium ® III (FC-PGA) 933 26,40 35,3409091<br />

Pentium ® III (FC-PGA) 1000 24,10 41,4937759<br />

Pentium ® III (FC-PGA2) 1000 29,00 34,4827586<br />

Pentium ® III (FC-PGA2) 1200 29,90 40,1337793<br />

Pentium ® III (FC-PGA2) 1266 29,50 42,9152542<br />

Pentium ® III (FC-PGA2) 1400 31,20 44,8717949<br />

Pentium ® 4-C 2400 67,60 35,5029586<br />

Pentium ® 4 HT 3060 81,80 37,408313<br />

Pentium ® 4 520J 2800 84,00 33,3333333<br />

Pentium ® 4 560J 3600 115,00 31,3043478<br />

Pentium ® D 805 2666 95,00 28,0631579<br />

Pentium ® D 820 2800 95,00 29,4736842<br />

Pentium ® D 920 2800 95,00 29,4736842<br />

Pentium ® D 940 3200 130,00 24,6153846<br />

Pentium ® D 960 3600 130,00 27,6923077<br />

Figura 5.41: TDP <strong>dei</strong> principali <strong>processori</strong> <strong>Intel</strong> ® per desktop dal Pentium ® II al<br />

Pentium ® D


206 Capitolo 5<br />

TDP [W]<br />

140,00<br />

120,00<br />

100,00<br />

80,00<br />

60,00<br />

40,00<br />

20,00<br />

0,00<br />

0 1000 2000 3000 4000<br />

Frequenza CPU [MHz]<br />

Figura 5.42 : TDP vs Frequenza <strong>di</strong> clock<br />

Pentium2<br />

Pentium3<br />

Pentium 4<br />

PentiumD


Capitolo 6<br />

Il nuovo processore Core i7<br />

<strong>Intel</strong> ® Core i7 è il nome con <strong>la</strong> quale le nuove CPU Quad Core <strong>Intel</strong> ® , hanno<br />

fatto il loro debutto sul mercato <strong>dei</strong> micro<strong>processori</strong>.<br />

I nuovi <strong>processori</strong> <strong>di</strong> casa <strong>Intel</strong> ® , presentano<br />

molte innovazioni dal punto <strong>di</strong> vista<br />

architetturale e prestazionale, battendo <strong>di</strong> fatto i<br />

"vecchi" Core 2 duo e Quad in tutti i test<br />

effettuati.<br />

Prima <strong>di</strong> approfon<strong>di</strong>re quelle che sono le<br />

caratteristiche del<strong>la</strong> nuova architettura, ecco un<br />

articolo, che traccia una linea (molto) generica<br />

sul<strong>la</strong> nuova famiglia <strong>di</strong> <strong>processori</strong> <strong>Intel</strong> ® .<br />

6.1 Elementi base del<strong>la</strong> nuova architettura<br />

Come già citato in precedenza, <strong>la</strong> nuova famiglia <strong>di</strong> CPU con microarchitettura<br />

Nehalem presenta importanti novità. Il progetto <strong>di</strong> ingegnerizzazione <strong>Intel</strong> ® ,<br />

mira ad ottenere il massimo delle prestazioni, in tutti i settori: Server, desktop e<br />

notebook.<br />

Di fatto, l’adattamento alle varie categorie, è stato reso possibile grazie al<strong>la</strong><br />

flessibilità <strong>di</strong> questa nuova architettura. <strong>Intel</strong> ® ha <strong>la</strong>vorato e <strong>la</strong>vorerà su tutti


208 Capitolo 6<br />

quegli elementi specifici che, accomunano tutte le categorie sopra menzionate,<br />

tese a migliorare le prestazioni, l’affidabilità e i consumi.<br />

L’implementazione <strong>dei</strong> nuovi Core i7 all’interno <strong>dei</strong> sistemi notebook, mira<br />

decisamente al contenimento <strong>dei</strong> consumi, mentre per i <strong>processori</strong> destinati<br />

all’utilizzo nei server, saranno implementati quantitativi maggiori <strong>di</strong> cache L3.<br />

Le principali novità introdotte in questa architettura sono:<br />

• Architettura quad core unificata: <strong>Intel</strong> ® per <strong>la</strong> nuova famiglia <strong>di</strong><br />

<strong>processori</strong> quad core ha adottato un design <strong>di</strong> tipo monolitico,<br />

posizionando tutti e quattro i core su un unico <strong>di</strong>e, da alloggiare<br />

successivamente all’interno del processore (ve<strong>di</strong> paragrafo 3.2.3).<br />

• Memory controller DDR3 integrato: novità assoluta per i <strong>processori</strong><br />

<strong>Intel</strong> ® . AMD ® introdusse questa tecnologia sin dal lontano 2003 con <strong>la</strong><br />

famiglia Opteron, con tutti i benefici che ne conseguirono.<br />

• Ritorno al<strong>la</strong> tecnologia HyperThrea<strong>di</strong>ng: Soluzione adottata da <strong>Intel</strong> ®<br />

nel lontano 2004 sui <strong>processori</strong> Pentium ® 4 (ve<strong>di</strong> paragrafo 5.4.5), poi<br />

abbandonata con l’arrivo delle più performanti CPU Core 2 duo.<br />

• Introduzione del bus QPI: acronimo <strong>di</strong> “Quick Path Interconnect”, in<br />

sostituzione al c<strong>la</strong>ssico “front side bus” o FSB. Questa tecnologia sarà<br />

adottata già, nelle prime versioni <strong>dei</strong> <strong>processori</strong> Core i7.<br />

• Istruzioni SSE4.1: Introdotte per <strong>la</strong> prima volta nel<strong>la</strong> famiglia Penryn,<br />

queste istruzioni sono <strong>la</strong> <strong>di</strong>retta evoluzione delle precedenti SSE4.0.


Il nuovo processore Core i7 209<br />

6.2 Design modu<strong>la</strong>re<br />

Un’altra interessante soluzione adottata da <strong>Intel</strong> ® con le nuove CPU e,<br />

l’introduzione <strong>di</strong> un “design modu<strong>la</strong>re”. Cosa significa?<br />

I primi Core i7 integrano 731 milioni <strong>di</strong> transistor, costruiti su un processo<br />

produttivo <strong>di</strong> 45 nanometri. Le successive <strong>evoluzioni</strong>, fermo restando che venga<br />

sfruttato il design modu<strong>la</strong>re, integreranno nuove funzionalità, tese ad aumentare<br />

le performance generali dell’architettura Nehalem.<br />

<strong>Intel</strong> ® dal canto suo, ha già presentato, al IDF Fall 2008, <strong>la</strong> serie Nehalem EX,<br />

CPU specificatamente de<strong>di</strong>cate ai sistemi server. Questa serie che, non vedrà <strong>la</strong><br />

luce, prima dal<strong>la</strong> fine del 2009, integrerà al suo interno 8 core fisici.<br />

Sempre all’IDF 2008 è stata presentata l’architettura che, dovrebbe concorrere<br />

<strong>di</strong>rettamente con le soluzioni AMD ® Fusion. Vale a <strong>di</strong>re l’integrazione in alcune<br />

soluzioni Nehalem, <strong>di</strong> una GPU, che occuperebbe <strong>la</strong> fascia bassa del mercato.<br />

Questa soluzione vedrà <strong>la</strong> luce non prima del 2010.<br />

6.3 Architettura dell’engine<br />

Prima <strong>di</strong> tutto gli ingegneri hanno aggiunto il supporto Macro-ops in modalità<br />

64 bit. Scelta giustificata per questa architettura che, non nasconde le sue<br />

ambizioni per il mercato server. L’utilizzo continuo delle Macro-ops è reso<br />

possibile grazie al maggior numero <strong>di</strong> istruzioni che l’architettura Nehalem è in<br />

grado <strong>di</strong> eseguire<br />

Le CPU del<strong>la</strong> famiglia Nehalem integrano un Execution Unit a 4 vie, capace, <strong>di</strong><br />

eseguire 4 operazioni <strong>di</strong> Decode, Rename e Retire in un singolo ciclo <strong>di</strong> clock.


210 Capitolo 6<br />

Questa tecnologia, già presente nel<strong>la</strong> precedente generazione Core 2, non è mai<br />

stata sfruttata a fondo a per via dal co<strong>di</strong>ce <strong>di</strong>sponibile sul mercato. Per questo<br />

motivo <strong>Intel</strong> ® è intervenuta in Neha<strong>la</strong>m espandendo il più possibile i Buffers<br />

interni, allo scopo <strong>di</strong> incrementare i benefici <strong>di</strong> un’architettura basata sul<br />

parallelismo.<br />

Un’altra interessante soluzione introdotta dal<strong>la</strong> precedente architettura e<br />

migliorata in Nehalem, è LSD, acronimo <strong>di</strong> “Loop Stream Director”.<br />

LSD non è altro che un buffer che immagazzina istruzioni, prossime<br />

all’esecuzione. Quando <strong>la</strong> CPU rileva un Loop (stessa istruzione ripetuta più<br />

volte), grazie al Loop stream Director, non è necessario effettuare un branch<br />

pre<strong>di</strong>ction o recuperare i dati dal<strong>la</strong> cache L1. In questo senso, possiamo <strong>di</strong>re<br />

che, LSD funge da memoria cache.


Il nuovo processore Core i7 211<br />

Figura 6.1 - Introduzione del "Loop Stream Detector"<br />

I guadagni che ne conseguono dall’utilizzo dell’LSD sono doppi: da una parte<br />

troviamo un minor consumo energetico, in quanto non vengono eseguite<br />

operazioni inutili, dall’altra avremo un incremento prestazionale grazie al<strong>la</strong><br />

riduzione del<strong>la</strong> pressione, sul<strong>la</strong> cache L1.<br />

Ulteriori miglioramenti sono stati apportati al Branch pre<strong>di</strong>ction. <strong>Intel</strong> ® non<br />

fornisce molti dati riguardanti i nuovi pre<strong>di</strong>ctor, ma si sa che sono composti da<br />

due livelli. Il primo è identico a quello utilizzato nei <strong>processori</strong> Core 2, mentre<br />

il secondo, con un accesso più lento, è in grado <strong>di</strong> immagazzinare più<br />

informazioni storiche. <strong>Intel</strong> ® tende a sottolineare come questa soluzione porti ad<br />

un incremento prestazionale con alcune applicazioni, che utilizzano un grosso<br />

volume <strong>di</strong> co<strong>di</strong>ce, come i database.


212 Capitolo 6<br />

6.4 HyperThrea<strong>di</strong>ng, ritorno al passato<br />

Il debutto delle CPU Core i7, vede il ritorno del<strong>la</strong> tecnologia HyperThrea<strong>di</strong>ng<br />

(ve<strong>di</strong> paragrafo 5.4.5). Questa soluzione introdotta nel<strong>la</strong> serie <strong>Intel</strong> ® Pentium ® 4,<br />

era stata abbandonata con l’arrivo sul mercato delle più performanti CPU Core<br />

2 duo e Quad.<br />

Per quale motivo <strong>Intel</strong> ® ha reintrodotto questa tecnologia so<strong>la</strong>mente ora, con<br />

l’arrivo dell’architettura Nehalem?<br />

I motivi sono sostanzialmente due:<br />

• In primis i nuovi <strong>processori</strong> Core i7 presentano per loro natura<br />

un’architettura molto ampia. Questa tecnologia trae beneficio<br />

<strong>di</strong>rettamente dal Memory controller integrato.<br />

• Come seconda cosa, i bassi costi <strong>di</strong> produzione che ne conseguono<br />

dall’adozione <strong>di</strong> questa soluzione.<br />

La tecnologia HyperThrea<strong>di</strong>ng permette <strong>di</strong> avere a <strong>di</strong>sposizione un numero<br />

doppio <strong>di</strong> core logici, rispetto a quelli presenti realmente all’interno del<br />

processore. Nel caso <strong>dei</strong> nuovi Core i7, con l’HyperThrea<strong>di</strong>ng attivato avremo a<br />

<strong>di</strong>sposizione del sistema operativo ben otto core logici.<br />

I benefici offerti da questa soluzione sono notevoli, soprattutto se utilizzata con<br />

applicazioni che operano su più core contemporaneamente.<br />

<strong>Intel</strong> ® ha fornito so<strong>la</strong>mente i dati <strong>di</strong> quelle applicazioni che, per loro natura<br />

sfruttano tutti i core presenti all’interno del<strong>la</strong> CPU.<br />

Come già scritto in precedenza, <strong>la</strong> tecnologia Simultaneous multithrea<strong>di</strong>ng trae<br />

beneficio <strong>di</strong>rettamente dal Memory controller integrato. Il controllo del<strong>la</strong>


Il nuovo processore Core i7 213<br />

memoria integrato all’interno del processore, soprattutto nell’implementazione<br />

triple channel, delle prime versioni delle CPU core i7, permette <strong>di</strong> avere a<br />

<strong>di</strong>sposizione quel quantitativo <strong>di</strong> banda passante (bandwidth) delle memoria, <strong>di</strong><br />

cui <strong>la</strong> tecnologia HyperThrea<strong>di</strong>ng ha bisogno per operare al meglio.<br />

È importante sottolineare come l’implementazione <strong>di</strong> più core fisici all’interno<br />

<strong>di</strong> un processore, comporti prestazioni nettamente superiori rispetto a soluzioni<br />

con Simultaneous multithrea<strong>di</strong>ng integrato. In altre parole, CPU che adottano <strong>la</strong><br />

tecnologia HyperThrea<strong>di</strong>ng non raggiungeranno mai le prestazioni <strong>di</strong> un<br />

processore con otto core nativi. È però vero che, l’implementazione del<br />

Simultaneous multithrea<strong>di</strong>ng per <strong>Intel</strong> ® risulta essere un’operazione abbastanza<br />

semplice e sopratutto "economica". Il numero ridotto <strong>di</strong> transistor utilizzato,<br />

uniti al<strong>la</strong> flessibilità <strong>di</strong> questa architettura, creano il connubio ideale tra<br />

prestazioni e costi <strong>di</strong> produzione.<br />

6.5 Modelli<br />

I primi modelli presentati dal produttore californiano, occuperanno <strong>la</strong> fascia<br />

me<strong>di</strong>o-alta del mercato delle CPU, spodestando dal trono le attuali soluzioni<br />

Core 2 Duo e Quad Q9550/9770, anche se non si prevede per quest’ultimi, una<br />

rapida uscita <strong>di</strong> scena, per via <strong>dei</strong> prezzi elevati, che presentano le nuove<br />

soluzioni Core i7.<br />

I modelli attualmente <strong>di</strong>sponibili presentano tutte le caratteristiche analizzate,<br />

fatta eccezione per alcuni modelli destinati al mercato server. Stiamo par<strong>la</strong>ndo<br />

ovviamente <strong>dei</strong> <strong>processori</strong> del<strong>la</strong> famiglia Xeon.


214 Capitolo 6<br />

I <strong>processori</strong> destinati al segmento desktop e già <strong>di</strong>sponibili sul mercato sono:<br />

• <strong>Intel</strong> ® Core i7 920: Frequenza <strong>di</strong> clock pari a 2.66 GHz, bus QPI <strong>di</strong> 4.8<br />

gigatransfert/secondo, Cache L3 8mbytes, memoria DDR3-1333, TDP<br />

massimo 130 Watt, Overspeed protection abilitata.<br />

• <strong>Intel</strong> ® Core i7 940: Frequenza <strong>di</strong> clock pari a 2.93 GHz, bus QPI <strong>di</strong> 4.8<br />

gigatransfert/secondo, Cache L3 8 mbytes, memoria DDR3-1333, TDP<br />

massimo 130 Watt, Overspeed protection abilitata.<br />

• <strong>Intel</strong> ® Core i7 965 Extreme: Frequenza <strong>di</strong> clock pari a 3.2 GHz, bus<br />

QPI <strong>di</strong> 6.4 gigatransfert/secondo, Cache L3 8 mbytes, memoria DDR3-<br />

1333, TDP massimo 130 Watt, Overspeed protection <strong>di</strong>sabilitata.<br />

I modelli 920 e 940 presentano le stesse<br />

caratteristiche tecniche, fatta eccezione per<br />

<strong>la</strong> frequenza <strong>di</strong> clock. Differenze sostanziali<br />

si notano invece con il modello top <strong>di</strong><br />

gamma del<strong>la</strong> famiglia Nehalem, ovvero il<br />

Core i7 945 Extreme. Quest’ultimo vede incrementata <strong>la</strong> frequenza <strong>di</strong> clok fino<br />

a 3.2 GHz, mentre il bus QPI raggiunge i 6.4 gigatransfert/secondo. Ultimo<br />

elemento <strong>di</strong> rielievo per il 965 Extreme, è sicuramente l’Overspeed protection<br />

<strong>di</strong>sabilitata.<br />

A partire dal secondo trimestre 2009, i modelli 965 Extreme e 940, saranno<br />

sostituiti dai nuovi 975 Extreme e 950.<br />

Il primo sarà caratterizzato da una frequnza <strong>di</strong> clock pari a 3.33 GHz, contro i<br />

3.2 GHz del modello attuale. Il secondo presenterà una frequenza operativa <strong>di</strong>


Il nuovo processore Core i7 215<br />

circa 3.06 GHz, contro i 2.83 GHz del modello 940. Il più piccolo del<strong>la</strong><br />

famiglia, 920, non verrà per ora sostituito.<br />

I modelli del<strong>la</strong> nuova serie, compreso il 920, saranno accomunati dell’utilizzo<br />

dello stepping D0. Questa ottimizzazione dovrebbe consentire margini <strong>di</strong><br />

overclok più elevati, oltre a una probabile <strong>di</strong>minuzione delle temperature.<br />

6.6 Architettura del<strong>la</strong> cache<br />

<strong>Intel</strong> ® ha introdotto importanti novità per quanto riguarda <strong>la</strong> struttura del<strong>la</strong><br />

cache. Se per <strong>la</strong> generazione precedente, Penryn, veniva utilizzata una cache L1<br />

per ciascun core e, una cache L2 sud<strong>di</strong>visa fra tutti i core, ora, con i nuovi Core<br />

i7 troviamo un cache L3, ovvero un terzo livello unificato fra i quattro core.<br />

Figura 6.2 - Schema a blocchi <strong>dei</strong> livelli <strong>di</strong> cache nei Core i7.


216 Capitolo 6<br />

La cache L1 con una grandezza <strong>di</strong> 64kbytes, sud<strong>di</strong>visa in due blocchi da<br />

32bytes, presenta tempi <strong>di</strong> <strong>la</strong>tenza superiori rispetto a quanto accadeva nelle<br />

CPU Core 2, essendo passati da tre a quattro cicli <strong>di</strong> clock.<br />

La cache L2 invece, <strong>di</strong>fferisce in modo sensibile da quel<strong>la</strong> implementata nelle<br />

precedenti soluzioni. Non più unificata fra tutti i core, ma specifica per ognuno<br />

<strong>di</strong> essi. Nel specifico, troviamo una quantitativo pari a 256kbytes, con una<br />

<strong>la</strong>tenza pari a 10 cicli <strong>di</strong> clock dal load, al<strong>la</strong> fuori uscita <strong>dei</strong> dati dal<strong>la</strong> cache.<br />

La cache L3 introdotta per <strong>la</strong> prima volta su <strong>processori</strong> <strong>Intel</strong> ® , è <strong>di</strong> tipo<br />

unificato; il suo quantitativo è pari a 8Mbytes. Tutta via, <strong>la</strong> cache L3 potrebbe<br />

assomigliare al<strong>la</strong> cache L2 utilizzata nelle CPU Core 2 Quad. Analisi più<br />

approfon<strong>di</strong>te però fanno sorgere una sostanziale <strong>di</strong>fferenza: nell’architettura<br />

Nehalem troviamo una cache L3 unificata tra tutti e quattro i core, mentre nei<br />

<strong>processori</strong> Core 2 Quad <strong>la</strong> cache L2 era sud<strong>di</strong>visa in due blocchi da 6Mbytes<br />

ciascuno, i quali venivano associati a una singo<strong>la</strong> coppia <strong>di</strong> core.<br />

Non a caso, nelle schede, che identificano le caratteristiche del processore (in<br />

questo caso CPU Core 2 Quad) è possibile trovare <strong>la</strong> quantità <strong>di</strong> cache L2 <strong>di</strong>visa<br />

per due (cache L2 = 6x2Mbytes).<br />

L’architettura del<strong>la</strong> cache integrata in Nehalem, è <strong>di</strong> tipo inclusivo: nel<br />

momento in cui un dato, non è presente nel<strong>la</strong> cache L3, l’architettura inclusiva,<br />

fa si che, il suddetto dato non risieda ne nel<strong>la</strong> cache L1 ne tanto meno in quel<strong>la</strong><br />

L2. Di conseguenza <strong>la</strong> CPU andrà a recuperare quel dato mancante <strong>di</strong>rettamente<br />

nel memory controller, evitando passaggi inutili (attraverso le varie cache) che,<br />

rallenterebbero il sistema.


Il nuovo processore Core i7 217<br />

6.7 Memory controller integrato<br />

L’ennesimo aspetto interessante, introdotto da <strong>Intel</strong> ® nel<strong>la</strong> nuova architettura<br />

Nehalem, è senz’altro l’implementazione del memory controller all’interno<br />

delle CPU Core i7.<br />

Dal canto suo, <strong>Intel</strong> ® segue quanto già effettuato dall’acerrimo rivale AMD ®<br />

che aveva introdotto il memory controller all’interno delle CPU destinate al<br />

mercato Server.<br />

Il memory controller utilizato da <strong>Intel</strong> ® è <strong>di</strong> tipo DDR3 a triplo canale,<br />

compatibile con i moduli DDR3 a 1066 MHz e DDR3 a 1333 MHz, <strong>la</strong> cui<br />

<strong>la</strong>rghezza <strong>di</strong> banda massima teorica è <strong>di</strong> 32 GB/s (gigabyte per secondo).<br />

Le successive versioni <strong>dei</strong> <strong>processori</strong> Core i7, integreranno un memory<br />

controller a doppio canale (dual-channel). Scelta giustificata, al fine <strong>di</strong> ridurre i<br />

costi, considerando che questa architettura sarà destinata anche ai segmenti<br />

value del mercato informatico.<br />

I vantaggi del memory controller integrato non si fermano <strong>di</strong> certo qui. <strong>Intel</strong> ® ha<br />

<strong>la</strong>vorato affinché le prestazioni migliorassero anche in ambito server.<br />

6.8 NUMA<br />

NUMA, acronimo <strong>di</strong> “non unifor memory acces”, permetterà <strong>di</strong> accedere al<br />

memory controller <strong>di</strong> altri <strong>processori</strong> montati sul<strong>la</strong> stessa scheda madre. Ci<br />

riferiamo ovviamente a piattaforme <strong>di</strong> tipo multi - socket. L’accesso ai dati nel<br />

memory controller <strong>di</strong> un altro processore, avverrà con un impatto prestazionale<br />

in termini <strong>di</strong> <strong>la</strong>rghezza <strong>di</strong> banda e <strong>la</strong>tenza. Il trade-off potrà però essere ridotto


218 Capitolo 6<br />

grazie a future applicazioni specificatamente sviluppate per l’architettura<br />

NUMA.<br />

6.9 QuickPath Interconnect<br />

Con <strong>la</strong> nuova architettura Nehalem, <strong>Intel</strong> ® introduce un nuovo bus <strong>di</strong><br />

collegamento tra processore, chipset e memory controller. Stiamo par<strong>la</strong>ndo del<br />

nuovo “QuickPath Interconnect”, il sostituto del<strong>la</strong> oramai vecchia architettura<br />

Front Side Bus, meglio conosciuta come FSB.<br />

Con il nuovo bus <strong>di</strong> connessione, <strong>di</strong> tipo point-to-point si raggiungono velocità<br />

teoriche <strong>di</strong> 12.5 gbps. Il limite, sempre teorico, <strong>di</strong> trasferimento sui link<br />

bi<strong>di</strong>rezionali è attestato intorno ai 25 gbps. In futuro <strong>Intel</strong> ® potrebbe<br />

incrementare <strong>la</strong> velocità <strong>di</strong> trasferimento dati tramite QPI, alzando le frequenze<br />

<strong>di</strong> trasmissione <strong>di</strong> quest’ultimo.<br />

Come accaduto per i memory controller integrato, <strong>Intel</strong> ® segue un approccio<br />

molto simile a quello adottato da AMD ® con il suo bus <strong>di</strong> connessione<br />

denominato HyperTransport.<br />

Data quin<strong>di</strong> <strong>la</strong> somiglianza fra le due tipologie <strong>di</strong> connessione, il bus QPI,<br />

rappresenterà per <strong>Intel</strong> ® un indubbio vantaggio unito al<strong>la</strong> nuova architettura<br />

Nehalem, soprattutto in ottica server.


Il nuovo processore Core i7 219<br />

6.10 Istruzioni SSE 4.2<br />

All’interno <strong>dei</strong> nuovi <strong>processori</strong> Core i7, <strong>Intel</strong> ® ha introdotto un nuovo set <strong>di</strong><br />

istruzioni appartenenti al<strong>la</strong> famiglia SSE. In Nehalem, queste istruzioni<br />

giungono al<strong>la</strong> versione 4.2 come anticipato nel paragrafo 5.7.2.<br />

6.11 Turbo Mode<br />

Turbo Mode, questo è il nome scelto da <strong>Intel</strong> ® , per identificare quello che è <strong>di</strong><br />

fatto un overclock <strong>di</strong>namico del<strong>la</strong> CPU.<br />

Una simile tecnologia è già stata introdotta da <strong>Intel</strong> ® nelle CPU Core 2 Duo, per<br />

sistemi notebook. Sussistono però, alcune importanti <strong>di</strong>fferenze.<br />

Nei <strong>processori</strong> Core 2 Duo, <strong>la</strong> tecnologia Turbo Mode interviene so<strong>la</strong>mente<br />

quando, uno <strong>dei</strong> due core entra in modalità idle (carico minimo), mantenendo<br />

un TDP massimo, entro i limiti previsti <strong>di</strong> default. In questo caso, il processore<br />

può entrare nel<strong>la</strong> modalità turbo mode so<strong>la</strong>mente quando, uno <strong>dei</strong> due core si<br />

trova in modalità risparmio energetico.<br />

In Nehalem <strong>la</strong> suddetta tecnologia è stata rivisitata totalmente: se un core risulta<br />

essere inattivo, viene attivata imme<strong>di</strong>atamente <strong>la</strong> funzione <strong>di</strong> risparmio<br />

energetico, incrementando <strong>la</strong> frequenza <strong>di</strong> clock <strong>dei</strong> restanti core attivi.<br />

L’incremento del<strong>la</strong> frequenza <strong>di</strong> clock avviene a seconda del carico <strong>di</strong> <strong>la</strong>voro<br />

richiesto e delle con<strong>di</strong>zioni <strong>di</strong> funzionamento del<strong>la</strong> CPU. Se il valore TDP <strong>di</strong> un<br />

dato istante, è tale da permettere un incremento delle frequenze <strong>di</strong> clock,<br />

automaticamente il processore opererà in questa <strong>di</strong>rezione.


220 Capitolo 6<br />

Figura 6.3 - Schema <strong>di</strong> base del funzionamento in Turbo Mode nel caso <strong>di</strong> alcuni core<br />

<strong>di</strong>sattivati.<br />

Analizzando quin<strong>di</strong>, quanto scritto sopra, è possibile definire <strong>la</strong> tecnologia<br />

Turbo mode come una sorta <strong>di</strong> overclock in tempo reale.<br />

La modalità Turbo Mode, può intervenire anche quando tutti i core presenti<br />

all’interno del<strong>la</strong> CPU, sono utilizzati al 100%, sfruttando margini residui <strong>di</strong><br />

<strong>di</strong>ssipazione termica e contando su un TDP, che in quel partico<strong>la</strong>re istante è<br />

inferiore al valore massimo definito <strong>di</strong> default, dal<strong>la</strong> casa produttrice.<br />

Appare evidente, che utilizzare un ottimo sistema <strong>di</strong> <strong>di</strong>ssipazione, non può che<br />

giovare, incrementando sempre più i margini d’intervento del<strong>la</strong> tecnologia<br />

Turbo Mode.<br />

Allo stato attuale, considerando i sistemi <strong>di</strong> raffreddamento o<strong>di</strong>erni, <strong>la</strong> modalità<br />

Turbo Mode, può alzare le frequenze <strong>dei</strong> singoli core <strong>di</strong> una o due volte <strong>la</strong><br />

frequenza <strong>di</strong> clock base del processore. Vale a <strong>di</strong>re che l’incremento delle<br />

frequenze operative del<strong>la</strong> CPU, possono essere <strong>di</strong> 133mhz o 266mhz.<br />

La modalità Turbo Mode, è comunque <strong>di</strong>sattivabile tramite bios.


Il nuovo processore Core i7 221<br />

Figura 6.4 - Schema <strong>di</strong> base del funzionamento in Turbo Mode nel caso <strong>di</strong> tutti i core<br />

attivi.<br />

6.12 Consumi<br />

<strong>Intel</strong> ® ha introdotto una gestione del risparmio energetico molto sofisticata,<br />

control<strong>la</strong>ta da una unità funzionale apposita detta PDU (Power Control Unit).<br />

PCU<br />

PCU acronimo <strong>di</strong> “Power Controll Unit”, è un sofisticato sistema <strong>di</strong> controllo,<br />

integrato all’interno delle CPU Nehalem, composto da circa un milione <strong>di</strong><br />

transistor. PCU integra al proprio interno un firmware, che monitorizza in<br />

tempo reale le temperature, i voltaggi e le frequenze <strong>di</strong> clock <strong>dei</strong> vari core,<br />

presenti all’interno del processore. Inoltre questo sistema <strong>di</strong> controllo, qualora<br />

fosse necessario, attiva o <strong>di</strong>sattiva <strong>la</strong> funzione turbo memory, analizzata sopra.


222 Capitolo 6<br />

Figura 6.5 - Power Contro Unit del<strong>la</strong> CPU Core i7<br />

<strong>Intel</strong> ® ha dotato ogni core presente all’interno del<strong>la</strong> CPU, <strong>di</strong> un proprio PLL.<br />

Questa soluzione permette un incremento del<strong>la</strong> frequenza <strong>di</strong> clock in<strong>di</strong>viduale<br />

per ciascun core.<br />

Questa tecnologia fu utilizzata per <strong>la</strong> prima volta da AMD ® con i <strong>processori</strong><br />

del<strong>la</strong> famiglia Phenom. Al pari del<strong>la</strong> soluzione AMD ® , <strong>Intel</strong> ® ha deciso <strong>di</strong> far<br />

operare tutti i core allo stesso voltaggio <strong>di</strong> alimentazione, in<strong>di</strong>pendentemente<br />

dal<strong>la</strong> potenza <strong>di</strong> calcolo richiesta ad ogni core. Per sopperire a questa mancanza,<br />

il colosso <strong>di</strong> Santa C<strong>la</strong>ra, ha utilizzato un approccio <strong>di</strong>fferente da quello adottato<br />

da AMD ® e sulle sue stesse CPU Core 2 duo.<br />

In Nehalem, ogni core può passare allo stato “C6” (ovvero, quando il voltaggio<br />

<strong>di</strong> alimentazione viene ridotto al minimo), in modo in<strong>di</strong>pendente, pur avendo un<br />

power p<strong>la</strong>in con<strong>di</strong>viso. Inoltre quando il sistema operativo, esegue l’istruzione<br />

C6 per un core che ha ultimato il suo processo, interviene imme<strong>di</strong>atamente <strong>la</strong>


Il nuovo processore Core i7 223<br />

fase <strong>di</strong> risparmio energetico (idle), portando il voltaggio del core interessato,<br />

prossimo allo zero, esattamente come se ci fosse un power p<strong>la</strong>in specifico per<br />

ogni core.<br />

I benefici resi possibili grazie a questa tecnologia, saranno importanti per le<br />

prime CPU Nehalem per notebook, attese al debutto nel corso <strong>di</strong> quest’anno,<br />

insieme al<strong>la</strong> nuova piattaforma Centrino.<br />

6.13 Considerazioni finali<br />

L’attenta analisi delle nuova architettura Nehalem evidenza come <strong>Intel</strong> ® sia<br />

riuscita ancora una volta a stupire il grande pubblico, con le prestazioni<br />

strabilianti <strong>dei</strong> sui <strong>processori</strong>.<br />

Anche se il <strong>di</strong>vario con <strong>la</strong> precedente generazione <strong>di</strong> <strong>processori</strong> non è così netto,<br />

<strong>Intel</strong> ® conserva il vantaggio acquisito sul<strong>la</strong> concorrenza nel lontano 2006, anno<br />

in cui fecero il loro debutto le prime CPU Core 2, all’epoca chiamate a<br />

raccogliere una pesante ere<strong>di</strong>tà <strong>la</strong>sciata dai <strong>processori</strong> del<strong>la</strong> famiglia Pentium ® 4.<br />

L’architettura Nehalem, non può essere considerata come rivoluzionaria, in<br />

quanto molte delle tecnologie sviluppate in passato da <strong>Intel</strong> ® sono state<br />

implementate nei nuovi <strong>processori</strong> Core i7. Inoltre il processo produttivo<br />

utilizzato per <strong>la</strong> costruzione <strong>di</strong> CPU del<strong>la</strong> famiglia Penryn, è lo stesso utilizzato<br />

<strong>dei</strong> <strong>processori</strong> basati su architettura Nehalem.<br />

Un altro aspetto molto interessante al<strong>la</strong> quale <strong>Intel</strong> ® tiene molto, per <strong>la</strong><br />

progettazione <strong>di</strong> future architetture, riguarda il “rapporto prestazioni–consumi”.


224 Capitolo 6<br />

Durante <strong>la</strong> fase <strong>di</strong> progettazione del<strong>la</strong> nuova architettura, il team <strong>di</strong> sviluppo,<br />

poteva implementare nuove funzionalità ma solo a patto che queste ultime,<br />

mantenessero un rapporto consumi-prestazioni <strong>di</strong> 1:2.


Capitolo 7<br />

Le architetture del futuro<br />

Nei precedenti capitoli abbiamo analizzato le mo<strong>di</strong>fiche <strong>architetturali</strong> che hanno<br />

caratterizzato i <strong>processori</strong> dell’ultimo decennio. Ne abbiamo dato una<br />

trattazione teorica nel Capitolo 3e abbiamo evidenziato nel Capitolo 5 come<br />

<strong>Intel</strong> ® , una delle più importanti aziende del settore, ha effettivamente<br />

implementato tali strategie nel<strong>la</strong> produzione <strong>dei</strong> suoi <strong>processori</strong>, a partire dal<br />

Pentium ® fino ad arrivare al nuovo processore i7 i cui primi esemp<strong>la</strong>ri sono<br />

usciti sul mercato in concomitanza del<strong>la</strong> stesura <strong>di</strong> questa tesi.<br />

In questo capitolo, invece, cercheremo <strong>di</strong> dare uno sguardo al futuro, cercando<br />

<strong>di</strong> delineare i limiti ormai raggiunti dalle correnti tecnologie ed evidenziando le<br />

possibili alternative per superarli.<br />

In partico<strong>la</strong>re valuteremo come le leggi <strong>di</strong> Amdahl (che abbiamo già trattato al<br />

paragrafo 2.4) e <strong>la</strong> <strong>legge</strong> <strong>di</strong> <strong>Moore</strong> possano essere lette al giorno d’oggi, nell’era<br />

cioè del multi core.<br />

7.1 La <strong>legge</strong> <strong>di</strong> Amdahl nell’era del multicore<br />

La <strong>legge</strong> <strong>di</strong> Amdahl, <strong>la</strong> cui formu<strong>la</strong>zione è stata riportata e descritta nel<br />

paragrafo 2.4, viene usata per calco<strong>la</strong>re il miglioramento atteso massimo in una<br />

architettura <strong>di</strong> calco<strong>la</strong>tori o in un sistema informatico quando vengono<br />

migliorate solo alcune parti del sistema stesso. In un certo senso, essa pone un


226 Capitolo 7<br />

limite al miglioramento massimo possibile, il quale è limitato dal<strong>la</strong> frazione <strong>di</strong><br />

tempo in cui <strong>la</strong> parte migliorata ha luogo. La <strong>legge</strong> <strong>di</strong> Amdahl può essere<br />

ulteriormente semplificata nel<strong>la</strong> pratica con una rego<strong>la</strong> che tutti i progettisti <strong>di</strong><br />

hardware devono tenere in considerazione: "Make the common case fast"<br />

(Ren<strong>di</strong> veloce il caso più frequente).<br />

Una srego<strong>la</strong>ta ricerca del miglioramento senza tenere in considerazione “il caso<br />

più frequente”, ovvero il tipo e le modalità <strong>di</strong> utilizzo dell’architettura stessa è<br />

sicuramente poco adeguata.<br />

<strong>Oltre</strong> al<strong>la</strong> ricerca <strong>di</strong> miglioramenti <strong>architetturali</strong> per <strong>la</strong> singo<strong>la</strong> unità sequenziale,<br />

è oggigiorno in<strong>di</strong>spensabile valutare i miglioramenti ottenuti me<strong>di</strong>ante <strong>la</strong><br />

parallelizzazione delle attività, sia a livello <strong>di</strong> multiprocessore che <strong>di</strong> multicore,<br />

<strong>di</strong> cui ci occuperemo in specifico in questa sezione.<br />

Innanzitutto, è interessante notare che per usi interattivi degli e<strong>la</strong>boratori è<br />

fondamentale il concetto <strong>di</strong> "velocità percepita", cioè <strong>la</strong> qualità <strong>di</strong> prestazione<br />

fornita dal computer percepita dall'utente. In questi termini <strong>di</strong>venta<br />

fondamentale il tempo <strong>di</strong> risposta ai coman<strong>di</strong>, il feedback fornito dal sistema,<br />

più che l'effettivo tempo <strong>di</strong> esecuzione <strong>dei</strong> job. In questo caso il fatto <strong>di</strong> avere<br />

più unità <strong>di</strong> calcolo potrebbe non tanto accelerare l'esecuzione <strong>di</strong> un processo<br />

quanto piuttosto dare <strong>la</strong> possibilità all'utente <strong>di</strong> continuare a sfruttare <strong>la</strong><br />

macchina anche durante l'esecuzione <strong>di</strong> un compito pesante.<br />

Inoltre, il multicore ha permesso, a <strong>di</strong>fferenza del caso multiprocessore, <strong>di</strong><br />

mantenere limitati i consumi <strong>di</strong> potenza e <strong>la</strong> <strong>di</strong>mensione, entrambi fattori non


Le architetture del futuro 227<br />

trascurabili. Il secondo, ad esempio, permette <strong>la</strong> realizzazione <strong>di</strong> bus dati <strong>di</strong><br />

collegamento tra i <strong>di</strong>versi core ad una più alta velocità rispetto alle architetture<br />

multiprocessore, sempre limitatamente al limite fisico imposto dal<strong>la</strong> velocità<br />

del<strong>la</strong> luce.<br />

La tecnologia multicore sembra quin<strong>di</strong> aver introdotto notevoli vantaggi e<br />

pertanto <strong>la</strong> sua <strong>di</strong>ffusione dovrebbe essere scontata e con<strong>di</strong>visa. In realtà non è<br />

così.<br />

Ad esempio, una visione poco rosea sul<strong>la</strong> sca<strong>la</strong>bilità <strong>dei</strong> sistemi multicore è<br />

quel<strong>la</strong> espressa da Hill e Marty [31]che basano le loro tesi proprio sul<strong>la</strong> <strong>legge</strong> <strong>di</strong><br />

Amdahl: essi affermano che <strong>la</strong> ineliminabile parte sequenziale <strong>di</strong> ogni<br />

e<strong>la</strong>borazione prende presto il sopravvento rispetto al<strong>la</strong> parte parallelizzabile<br />

me<strong>di</strong>ante <strong>la</strong> tecnologia multicore.<br />

La <strong>legge</strong> <strong>di</strong> Amdahl, infatti, può essere riscritta per tenere in considerazione lo<br />

speedup ottenuto introducendo più unità <strong>di</strong> calcolo. In tal caso, <strong>la</strong> frazione f che<br />

può essere migliorata è quel<strong>la</strong> paralle<strong>la</strong>, e il miglioramento ottenuto in questa<br />

so<strong>la</strong> parte è, nel caso migliore, proporzionale al numero m <strong>di</strong> <strong>processori</strong> (core).<br />

Per maggior precisione, si potrebbe definire una funzione del numero <strong>di</strong> core<br />

che rego<strong>la</strong> tale miglioramento.<br />

Speedup Amdhal<br />

=<br />

1<br />

( 1−<br />

)<br />

f +<br />

f<br />

m<br />

(7.1)<br />

Sotto questa ipotesi, l’aumento del numero <strong>di</strong> core ha sì un vantaggio che però è<br />

progressivamente insufficiente a coprire <strong>la</strong> crescente complessità architetturale.


228 Capitolo 7<br />

Questa visione pessimistica è probabilmente con<strong>di</strong>visa dai gran<strong>di</strong> produttori <strong>di</strong><br />

<strong>processori</strong>, che stanno realizzando architetture con un numero molto limitato <strong>di</strong><br />

core. Si vedano ad esempio l’IBM Cell[32] e il processore T2 del<strong>la</strong> Sun<br />

Microsystems [33], entrambi a 8 core, o il processore Dunningotn dell’ <strong>Intel</strong> ®<br />

[34], annunciato l’anno scorso, a soli 6 core. Sempre <strong>Intel</strong> ® ha in progetto per il<br />

2011 un processore a 80 core, ma il suo approccio è ancora molto conservatore<br />

rispetto a piccole e più flessibili compagnie che stanno producendo <strong>processori</strong> a<br />

centinaia <strong>di</strong> core [35; 36]. La storia sembra ripetersi, visto che simili<br />

comportamenti si sono verificati alcuni decenni fa con le architetture<br />

multiprocessore.<br />

In contrasto con <strong>la</strong> visione pessimistica <strong>di</strong> Hill e Marty, Sun e Chen dell’Illinois<br />

Institute of Technology hanno recentemente <strong>di</strong>ffuso un report in cui riportano il<br />

loro ottimismo nello sviluppo del<strong>la</strong> tecnologia multicore [37]<br />

La <strong>legge</strong> <strong>di</strong> Amdahl, matematicamente corretta, contiene in effetti alcune ipotesi<br />

che non sempre vengono completamente considerate e riportate, portando ad<br />

una spesso errata e pessimistica visione delle possibilità <strong>di</strong> speedup ottenuta col<br />

parallelismo.<br />

L’equazione 7.1 suppone che il carico <strong>di</strong> <strong>la</strong>voro sia costante. Tale equazione,<br />

infatti, prende anche il nome <strong>di</strong> “fixed-size speedup model”. In realtà, avendo a<br />

<strong>di</strong>sposizione più potenza <strong>di</strong> calcolo, le richieste dell’utente spesso aumentano.<br />

Anche se il carico <strong>di</strong> <strong>la</strong>voro iniziale a causa del<strong>la</strong> parte sequenziale non è


Le architetture del futuro 229<br />

ottimizzabile oltre una certa soglia, l’aumento <strong>di</strong> operazioni che possono essere<br />

eseguite nello stesso periodo <strong>di</strong> tempo è comunque un vantaggio che<br />

l’equazione <strong>di</strong> Amdahl non considera. A tal proposito, Gustafson ha introdotto<br />

una variante detta “fixed-time speedup model”.<br />

Tale speedup è calco<strong>la</strong>to come rapporto fra il carico <strong>di</strong> <strong>la</strong>voro che si riesce a<br />

processare nell’unità <strong>di</strong> tempo con <strong>la</strong> versione sequenziale e <strong>la</strong> rispettiva<br />

soluzione parallelizzata.<br />

Speedup FT<br />

=<br />

( 1 )<br />

− f + mf<br />

(7.2)<br />

Come si può notare, in questa formu<strong>la</strong>zione all’aumentare del numero m <strong>di</strong><br />

<strong>processori</strong> lo speedup ha un aumento proporzionale, teoricamente infinito per m<br />

che tende all’infinito.<br />

Purtroppo anche questa seconda formu<strong>la</strong>zione non tiene conto <strong>di</strong> un collo <strong>di</strong><br />

bottiglia dell’intero sistema, ovvero dell’accesso al<strong>la</strong> memoria.<br />

Sun e Chen, nel loro report, riportano una nuova formu<strong>la</strong>zione che generalizza<br />

sia <strong>la</strong> <strong>legge</strong> <strong>di</strong> Amdahl che quel<strong>la</strong> <strong>di</strong> Gustafson, nota col nome <strong>di</strong> “memory-<br />

bounded speedup”.<br />

In questa nuova ottica, il miglioramento ottenuto con <strong>la</strong> tecnologia multicore<br />

rimane comunque più che vantaggiosa. In Figura 7.1, Figura 7.2 e Figura 7.3<br />

vengono mostrati gli speedup ottenuti con un numero <strong>di</strong> core crescente nelle tre<br />

formu<strong>la</strong>zioni. Tutti e tre i casi mostrano come <strong>la</strong> visione <strong>di</strong> Amdahl sia non<br />

tanto errata, ma comunque incompleta e pessimista.


230 Capitolo 7<br />

Figura 7.1 – Fixed-Size Speedup <strong>di</strong> una architettura multicore.[37]<br />

Figura 7.2 - Fixed-Time Speedup <strong>di</strong> una architettura multicore [37]


Le architetture del futuro 231<br />

Figura 7.3 - Memory-Bounded Speedup <strong>di</strong> una architettura multicore [37]<br />

E’ quin<strong>di</strong> evidente come l’era del multicore stia rivoluzionando il modo <strong>di</strong><br />

pensare e gli assiomi su cui si basavano le scelte progettuali degli scorsi<br />

decenni. Analizziamo più in dettaglio quali sono i nuovi pi<strong>la</strong>stri su cui si deve<br />

basare il futuro prossimo dell’architettura <strong>dei</strong> calco<strong>la</strong>tori.<br />

7.2 Una rivoluzione del pensiero comune<br />

Come suggerito nel precedente paragrafo, è fondamentale conoscere cosa si<br />

vuole fare con una architettura per poter migliorare il caso più frequente e più<br />

pesante.<br />

Recentemente David Patterson, docente universitario <strong>di</strong> Informatica e in<br />

partico<strong>la</strong>re <strong>di</strong> Architettura <strong>dei</strong> calco<strong>la</strong>tori presso <strong>la</strong> University of California,


232 Capitolo 7<br />

Berkeley sin dal 1977, ha stu<strong>di</strong>ato ed esposto insieme ad altri ricercatori un<br />

report sul futuro delle architetture <strong>dei</strong> calco<strong>la</strong>tori [38]. Patterson fu uno <strong>dei</strong><br />

pionieri dell'architettura RISC e del<strong>la</strong> tecnologia RAID, ambedue ampiamente<br />

utilizzate nei moderni e<strong>la</strong>boratori. Presidente del<strong>la</strong> Association for Computing<br />

Machinery (ACM) dal 2004 e 2006 è sicuramente una delle voci più autorevoli<br />

nel settore.<br />

Il report in questione parte dall’evidente mutazione dello scenario tecnologico<br />

attuale. In partico<strong>la</strong>re, afferma che è notevolmente cambiato il pensiero comune:<br />

le basi su cui si fondavano <strong>la</strong> progettazione e lo sviluppo <strong>di</strong> nuovi calco<strong>la</strong>tori<br />

nello scorso secolo non sono più valide. Patterson ritiene quin<strong>di</strong> in<strong>di</strong>spensabile<br />

favorire un nuovo incontro e scambio <strong>di</strong> idee tra le varie <strong>di</strong>scipline, dal<strong>la</strong><br />

architettura allo sviluppo <strong>dei</strong> linguaggi <strong>di</strong> programmazione, agli analisti<br />

numerici, ai programmatori.<br />

Le promesse del “parallelismo” hanno affascinato i ricercatori negli ultimi<br />

trent’anni. Nonostante le architetture parallele siano in fase <strong>di</strong> stu<strong>di</strong>o e<br />

produzione da svariato tempo, le architetture monoprocessore hanno sempre<br />

prevalso, in partico<strong>la</strong>re per motivi economici e per <strong>la</strong> <strong>di</strong>ffuse preferenza alle<br />

architetture “general-purpose”. Ultimamente invece, si è riscoperto un notevole<br />

interesse per il parallelismo; non solo, ci si è mossi oserei <strong>di</strong>re senza possibilità<br />

<strong>di</strong> ritorno verso <strong>di</strong> esso.


Le architetture del futuro 233<br />

Ecco le ragioni <strong>di</strong> queste mutazioni, esposte in contrapposizione ai principi<br />

vali<strong>di</strong> fino a qualche anno fa, come riportate da Patterson in [4]<br />

PASSATO PRESENTE<br />

La potenza <strong>di</strong>ssipata è gratis, quello<br />

che costa sono i transistori<br />

L’unica potenza da tenere in<br />

considerazione è quel<strong>la</strong> <strong>di</strong>namica;<br />

I <strong>processori</strong> monolitici in silicio sono<br />

internamente affidabili; i problemi<br />

nascono ai pin<br />

I ricercatori <strong>di</strong>mostravano le loro<br />

nuove architetture ed idee per mezzo<br />

<strong>di</strong> prototipi<br />

Nel<strong>la</strong> progettazione <strong>di</strong> nuove<br />

tecnologie bisogna dare ampio spazio<br />

sia al<strong>la</strong> <strong>la</strong>rghezza <strong>di</strong> banda che al<strong>la</strong><br />

<strong>la</strong>tenza<br />

Moltiplicare e <strong>di</strong>videre sono<br />

operazioni lente; i trasferimenti sono<br />

operazioni veloci<br />

L’ILP può essere migliorato tramite<br />

nuovi compi<strong>la</strong>tori e mo<strong>di</strong>fiche<br />

<strong>architetturali</strong> (out-of-order,<br />

specu<strong>la</strong>tion, ecc).<br />

Attualmente è il contrario. Soprattutto<br />

con <strong>la</strong> <strong>di</strong>ffusione del portatili c’è un<br />

continuo interesse per <strong>la</strong> riduzione<br />

del<strong>la</strong> potenza <strong>di</strong>ssipata, mentre le<br />

<strong>evoluzioni</strong> tecnologiche hanno portato<br />

ad un “esubero” <strong>di</strong> transistor a<br />

<strong>di</strong>sposizione (Power Wall)<br />

Per desktop e server <strong>la</strong> potenza statica<br />

raggiunge ad<strong>di</strong>rittura il 40% del totale<br />

Da quando si è scesi al <strong>di</strong> sotto <strong>dei</strong><br />

65nm, esistono errori non nulli<br />

[39][40]<br />

I costi delle maschere, del<strong>la</strong><br />

progettazione e realizzazione sono<br />

troppo alti per produrre so<strong>la</strong>mente<br />

prototipi realistici. Servono nuove<br />

tecniche per <strong>la</strong> progettazione<br />

La <strong>la</strong>rghezza <strong>di</strong> banda evolve in modo<br />

quadratico rispetto al<strong>la</strong> <strong>la</strong>tenza, che<br />

necessità <strong>di</strong> maggior sforzo [41]<br />

Le moltiplicazioni sono realizzabili in<br />

4 cicli <strong>di</strong> clock; nuovi stu<strong>di</strong><br />

evidenziano che anche le <strong>di</strong>visioni non<br />

sono più un problema [42]. Le attuali<br />

architetture richiedono intorno ai 200<br />

cicli <strong>di</strong> clock per accedere al<strong>la</strong><br />

DRAM. (Memory wall [43]).<br />

Ulteriori tecniche per migliorare l’ILP<br />

stanno rive<strong>la</strong>ndosi sempre meno<br />

interessanti ed efficaci (ILP Wall<br />

[44]).<br />

Le performance <strong>dei</strong> mono<strong>processori</strong> In Figura 7.4 sono riportate le


234 Capitolo 7<br />

PASSATO PRESENTE<br />

raddoppiano ogni 18 mesi performance <strong>dei</strong> <strong>processori</strong> dal 1978<br />

al 2006 utilizzando benchmark SPEC<br />

[45]. L’incremento <strong>di</strong> prestazioni fino<br />

al 1984 era intorno al 25% annuo; <strong>la</strong><br />

<strong>di</strong>ffusione del para<strong>di</strong>gma RISC ha<br />

permesso uno sviluppo annuo del 52%<br />

fino al 2002; dopo tale data, invece, si<br />

è tornati ad un incremento annuo<br />

modesto, intorno al 20%.<br />

Ciò è dovuto al<strong>la</strong> combinazione <strong>dei</strong><br />

“tre muri”:<br />

Power Wall + Memory Wall + ILP<br />

Wall = Brck Wall<br />

Non ha senso sforzarsi per<br />

parallelizzare il co<strong>di</strong>ce: presto nuove<br />

architetture realizzeranno quanto<br />

voluto ad una velocità sufficiente<br />

L’incremento del<strong>la</strong> frequenza del<br />

clock è <strong>la</strong> via principale per migliorare<br />

le performance<br />

Una applicazione multiprocessore<br />

deve avere prestazioni con crescita<br />

lineare rispetto al numero <strong>di</strong><br />

<strong>processori</strong>, altrimenti è una sconfitta<br />

L’hardware è poco flessibile, il<br />

software invece è facilmente adattabile<br />

Non posso sapere le applicazioni del<br />

futuro; valuto le nuove mo<strong>di</strong>fiche<br />

<strong>architetturali</strong> me<strong>di</strong>ante un insieme <strong>di</strong><br />

vecchi programmi SPEC2006 [45]<br />

Calco<strong>la</strong>tori più efficienti per<br />

l’esecuzione <strong>di</strong> co<strong>di</strong>ce sequenziale<br />

saranno <strong>di</strong>sponibili sempre più tar<strong>di</strong><br />

Siamo arrivati ad un limite fisico del<strong>la</strong><br />

velocità del clock (ve<strong>di</strong> paragrafo<br />

2.3.2). Il parallelismo deve essere al<br />

centro dell’attenzione<br />

Qualunque miglioramento si ottiene è<br />

ben accetto<br />

Il software è più <strong>di</strong>fficile da migliorare<br />

e cambiare<br />

E’ fondamentale prevedere le<br />

applicazioni del futuro<br />

Tabel<strong>la</strong> 7.1 - Principi vali<strong>di</strong> fino a qualche anno fa ed ora ormai sorpassati.


Le architetture del futuro 235<br />

Performance (vs. VAX-11/780)<br />

10000<br />

1000<br />

100<br />

10<br />

25%/year<br />

52%/year<br />

??%/year<br />

1<br />

1978 1980 1982 1984 1986 1988 1990 1992 1994 1996 1998 2000 2002 2004 2006<br />

Figura 7.4 - L’incremento <strong>di</strong> prestazioni fino al 1984 era intorno al 25% annuo; <strong>la</strong><br />

<strong>di</strong>ffusione del para<strong>di</strong>gma RISC ha permesso uno sviluppo annuo del 52% fino al 2002;<br />

dopo tale data, invece, si è tornati ad un incremento annuo modesto, intorno al 20%.[4]<br />

Il quadro che se ne evince sembra essere molto negativo; in realtà esistono<br />

altrettanti contro aspetti positivi. Innanzitutto <strong>la</strong> <strong>legge</strong> <strong>di</strong> <strong>Moore</strong> continua a<br />

valere. Come riportato nel titolo <strong>di</strong> questa tesi, le mo<strong>di</strong>fiche <strong>architetturali</strong><br />

devono andare ben oltre tale <strong>legge</strong>, ma <strong>la</strong> riduzione delle <strong>di</strong>mensioni <strong>dei</strong><br />

transistor e il conseguente aumento del numero degli stessi all’interno dello<br />

stesso processore hanno permesso interessanti applicazioni. Ad esempio, nel<br />

2005 è stato ri<strong>la</strong>sciato dal<strong>la</strong> CISCO un chip che integrava ben 188 core <strong>di</strong> tipo<br />

RISC [46]. La possibilità <strong>di</strong> trasmissioni a bassa <strong>la</strong>tenza ed alta banda<br />

all’interno dello stesso chip permettono una nuova modalità <strong>di</strong> progettazione <strong>di</strong><br />

architetture, che vedono integrare numerosi core all’interno dello stesso chip. Si<br />

può quasi pensare al core come in nuovo elemento <strong>di</strong> base al posto del


236 Capitolo 7<br />

transistor. La strategia multicore sembra quin<strong>di</strong> essere <strong>la</strong> soluzione più<br />

promettente nell’ambito del<strong>la</strong> progettazione delle nuove architetture.<br />

7.3 “I sette nani”<br />

Come già anticipato, Patterson sostiene che è necessario uno sforzo comune per<br />

<strong>la</strong> progettazione <strong>di</strong> nuove architetture da parte <strong>di</strong> <strong>di</strong>verse <strong>di</strong>scipline. In<br />

partico<strong>la</strong>re, come evidenziato dalle ultime due <strong>evoluzioni</strong> del pensiero comune<br />

(Tabel<strong>la</strong> 7.1) è fondamentale uno stretto legame tra software e hardware, o<br />

meglio tra architetture ed applicazioni.<br />

Figura 7.5 - “A view from Berkeley”: sette punti fondamentali per il calcolo parallelo<br />

del 21° secolo. Figura ispirata al<strong>la</strong> vista del Goldon Gate Bridge da Berkeley<br />

Tra i sette i punti fondamentali da tenere in considerazione c’è anche <strong>la</strong><br />

tipologia delle applicazioni; non più le applicazioni del passato come avveniva<br />

me<strong>di</strong>ante lo stu<strong>di</strong>o <strong>dei</strong> Benchmark SPEC, ma le applicazioni del futuro.


Le architetture del futuro 237<br />

A tal proposito Phil Colel<strong>la</strong> nel 2004 identificò sette algoritmi numerici che<br />

riteneva essere al<strong>la</strong> base del<strong>la</strong> scienza e dell’ingegneria almeno per le future<br />

deca<strong>di</strong> [47].<br />

• Algebra lineare densa<br />

• Algebra lineare sparsa<br />

• Meto<strong>di</strong> spettrali (es. FFT)<br />

• Meto<strong>di</strong> a particelle<br />

• Griglie <strong>di</strong> calcolo strutturate<br />

• Griglie <strong>di</strong> calcolo non strutturate<br />

• Meto<strong>di</strong> Monte Carlo<br />

Questi sette algoritmi, detti 7 nani (seven dwarfs) sono stati stu<strong>di</strong>ati e<br />

c<strong>la</strong>ssificati in altrettante c<strong>la</strong>ssi <strong>di</strong> equivalenza, sotto le quali numerosi algoritmi<br />

trovano spazio. Una prova <strong>di</strong> ciò può essere ottenuta analizzando librerie<br />

software per l’analisi numerica. I pattern <strong>di</strong> e<strong>la</strong>borazione e <strong>di</strong> scambio <strong>dei</strong> dati<br />

che caratterizzano ciascuna c<strong>la</strong>sse possono essere <strong>di</strong> gran<strong>di</strong>ssimo interesse per <strong>la</strong><br />

progettazione <strong>di</strong> nuove architetture che devono rispondere a suddette esigenze.<br />

Un approccio simile a quello <strong>di</strong> Colel<strong>la</strong> è stato seguito sempre da Patterson che<br />

ha stu<strong>di</strong>ato i 41 kernel <strong>di</strong> EEMBC e i 26 programmi SPEC2006.<br />

Successivamente ha analizzato le tre <strong>di</strong>scipline <strong>di</strong> enorme interesse attuale:<br />

Machine learning, Database software e Computer Graphics and Games. Da tale<br />

stu<strong>di</strong>o sono stati rintracciati 6 ulteriori “nani”:<br />

• Logica combinatoria (crittografia)


238 Capitolo 7<br />

• Visita <strong>dei</strong> Grafi (quicksort)<br />

• programmazione <strong>di</strong>namica (problemi <strong>di</strong> ottimizzazione)<br />

• Backtrack and branch&Bound (problemi <strong>di</strong> ottimizzazione in<br />

sottodomini)<br />

• Modelli grafici (MRF, HMM)<br />

• Macchine a stati finiti<br />

7.4 Lo stu<strong>di</strong>o dell’ <strong>Intel</strong> ® : RMS<br />

Anche <strong>Intel</strong> ® ha affrontato lo stesso problema. Come evidenziato da Dubey, l’<br />

<strong>Intel</strong> ® crede che l’incremento delle richieste degli utenti sarà principalmente<br />

legato dal<strong>la</strong> necessità <strong>di</strong> processare gran<strong>di</strong> quantità <strong>di</strong> dati (siamo entrati<br />

nell’Era del Tera [48]). <strong>Intel</strong> ® ha quin<strong>di</strong> c<strong>la</strong>ssificato le applicazioni <strong>di</strong> interesse<br />

in tre categorie: Recognition, Mining e Synthesis (RMS).<br />

• Recognition: me<strong>di</strong>ante tecniche <strong>di</strong> machine learning si devono<br />

analizzare i dati per trovare un modello matematico che li rappresenti<br />

• Mining: ricerca nel web <strong>di</strong> tutte le istanze che verificano il modello<br />

trovato<br />

• Synthesis: creazione <strong>di</strong> nuovi modelli o nuove istanze.<br />

La c<strong>la</strong>ssificazione RMS è molto simile allo stu<strong>di</strong>o <strong>di</strong> Patterson sulle tecniche <strong>di</strong><br />

Machine Learning, database e grafica. <strong>Intel</strong> ® ritiene inoltre che il modello RMS<br />

avrà notevoli applicazioni nei campi del<strong>la</strong> me<strong>di</strong>cina, del<strong>la</strong> finanza, <strong>dei</strong><br />

videogame nonché in ambito domestico. Nello schema <strong>di</strong> Figura 7.6 sono<br />

riportate le c<strong>la</strong>ssi <strong>di</strong> funzioni e primitive <strong>di</strong> partico<strong>la</strong>re interesse, che derivano


Le architetture del futuro 239<br />

dalle <strong>di</strong>scipline <strong>di</strong> Computer Vision (Recognition), Data Mining (Mining) e<br />

Rendering Physical Simu<strong>la</strong>tion, Financial Analytics (Synthesis).<br />

Figura 7.6 – <strong>Intel</strong> RMS. Generazione delle primitive <strong>di</strong> e<strong>la</strong>borazione (in basso) a<br />

partire dalle 5 categorie (in alto): Computer Vision (Recognition), Data Mining<br />

(Mining) e Rendering Physical Simu<strong>la</strong>tion, Financial Analytics (Synthesis) [49]<br />

Riassumendo, le applicazioni <strong>di</strong> interesse per il futuro sono riportate in Figura<br />

7.7.<br />

Dwarf Embedde<br />

d<br />

Computin<br />

g<br />

1. Dense<br />

Linear<br />

Algebra<br />

(e.g., BLAS<br />

or<br />

MATLAB)<br />

EEMBC<br />

Automotive:<br />

iDCT, FIR,<br />

IIR, Matrix<br />

Arith;<br />

EEMBC<br />

Consumer:<br />

JPEG, RGB<br />

to CMYK,<br />

RGB to<br />

YIQ;<br />

EEMBC<br />

Digital<br />

General<br />

Purpose<br />

Computin<br />

g<br />

SPEC<br />

Integer:<br />

Quantum<br />

computer<br />

simu<strong>la</strong>tion<br />

(libquantum),<br />

video<br />

compression<br />

(h264avc)<br />

SPEC Fl. Pl.:<br />

Hidden<br />

Markov<br />

models<br />

Machine<br />

Learning<br />

Support<br />

vector<br />

machines,<br />

princpal<br />

componen<br />

t analysis,<br />

independe<br />

nt<br />

componen<br />

t<br />

analysis<br />

Graphic<br />

s /<br />

Games<br />

Databas<br />

es<br />

Database<br />

hash<br />

accesses<br />

<strong>la</strong>rge<br />

contiguous<br />

sections of<br />

memory<br />

<strong>Intel</strong> ®<br />

RMS<br />

Body<br />

Tracking,<br />

me<strong>di</strong>a<br />

synthesis<br />

linear<br />

programmin<br />

g, K<br />

means,<br />

support<br />

vector<br />

machines,<br />

quadratic<br />

programmin


240 Capitolo 7<br />

Dwarf Embedde<br />

d<br />

Computin<br />

g<br />

Entertainme<br />

nt: RSA<br />

MP3<br />

Decode,<br />

MPEG-2<br />

Decode,<br />

MPEG-2<br />

Encode,<br />

MPEG-4<br />

Decode;<br />

MPEG-4<br />

Encode;<br />

EEMBC<br />

Networking:<br />

IP Packet;<br />

EEMBC<br />

Office<br />

Automation:<br />

Image<br />

Rotation;<br />

EEMBC<br />

Telecom:<br />

Convolution<br />

Encode;<br />

EEMBC<br />

Java: PNG<br />

2. Sparse<br />

Linear<br />

Algebra<br />

(e.g., SpMV,<br />

OSKI, or<br />

SuperLU)<br />

3. Spectral<br />

Methods<br />

(e.g., FFT)<br />

4. N-Body<br />

Methods<br />

(e.g., Barnes-<br />

Hut, Fast<br />

Multipole<br />

Method)<br />

EEMBC<br />

Automotive:<br />

Basic Int +<br />

FP, Bit<br />

Manip, CAN<br />

Remote<br />

Data, Table<br />

Lookup,<br />

Tooth to<br />

Spark;<br />

EEMBC<br />

Telecom: Bit<br />

Allocation;<br />

EEMBC<br />

Java: PNG<br />

EEMBC<br />

Automotive:<br />

FFT, iFFT,<br />

iDCT;<br />

EEMBC<br />

Consumer:<br />

JPEG;<br />

EEMBC<br />

Entertainme<br />

nt: MP3<br />

Decode<br />

General<br />

Purpose<br />

Computin<br />

g<br />

Machine<br />

Learning<br />

Graphic<br />

s /<br />

Games<br />

Databas<br />

es<br />

<strong>Intel</strong> ®<br />

RMS<br />

(sphinx3) g,<br />

PDE: Face,<br />

PDE:<br />

Cloth*<br />

SPEC Fl. Pt.:<br />

Fluid<br />

dynamics<br />

(bwaves),<br />

quantum<br />

chemistry<br />

(gamess;<br />

tonto), linear<br />

program<br />

solver<br />

(soplex)<br />

SPEC Fl. Pt.:<br />

Molecu<strong>la</strong>r<br />

dynamics<br />

(gromacs, 32bit;<br />

nAMD ® ,<br />

64-bit)<br />

Support<br />

vector<br />

machines,<br />

principal<br />

componen<br />

t analysis,<br />

independe<br />

nt<br />

componen<br />

t analysis<br />

Spectral<br />

clustering<br />

Reverse<br />

kinematic<br />

s; Spring<br />

models<br />

Texture<br />

maps<br />

Support<br />

vector<br />

machines,<br />

quadratic<br />

programmin<br />

g, PDE:<br />

Face, PDE:<br />

Cloth*<br />

PDE:<br />

Computatio<br />

nal fluid<br />

dynamics<br />

PDE:<br />

Computatio<br />

nal fluid<br />

dynamics<br />

PDE: Cloth


Le architetture del futuro 241<br />

Dwarf Embedde<br />

d<br />

Computin<br />

g<br />

5. Structured<br />

Grids (e.g.,<br />

Cactus or<br />

Lattice<br />

Boltzmann<br />

Magneto-<br />

hydrodynami<br />

cs)<br />

6.<br />

Unstructured<br />

Grids (e.g.,<br />

ABAQUS or<br />

FIDAP)<br />

7.<br />

MapReduce<br />

(e.g., Monte<br />

Carlo)<br />

8.<br />

Combination<br />

al Logic<br />

EEMBC<br />

Automotive:<br />

FIR, IIR;<br />

EEMBC<br />

Consumer:<br />

HP Gray-<br />

Scale;<br />

EEMBC<br />

Consumer:<br />

JPEG;<br />

EEMBC<br />

Digital<br />

Entertainme<br />

nt:<br />

MP3<br />

Decode,<br />

MPEG-2<br />

Decode,<br />

MPEG-2<br />

Encode,<br />

MPEG-4<br />

Decode;<br />

MPEG-4<br />

Encode;<br />

EEMBC<br />

Office<br />

Automation:<br />

Dithering;<br />

EEMBC<br />

Telecom:<br />

Autocorre<strong>la</strong>t<br />

ion<br />

EEMBC<br />

Digital<br />

Entertainme<br />

nt: AES,<br />

DES ;<br />

EEMBC<br />

Networking:<br />

IP Packet, IP<br />

NAT, Route<br />

Lookup;<br />

EEMBC<br />

Office<br />

Automation:<br />

Image<br />

Rotation;<br />

EEMBC<br />

Telecom:<br />

General<br />

Purpose<br />

Computin<br />

g<br />

SPEC Fl. Pt.:<br />

Quantum<br />

chromodyna<br />

mics<br />

(milc),magnet<br />

o<br />

hydrodynami<br />

cs (zeusmp),<br />

general<br />

re<strong>la</strong>tivity<br />

(cactusADM),<br />

fluid<br />

dynamics<br />

(leslie3d-<br />

AMR; lbm),<br />

finite element<br />

methods<br />

(dealII-AMR;<br />

calculix),<br />

Maxwell’s<br />

E&M<br />

eqns solver<br />

(GemsFDTD)<br />

, quantum<br />

crystallograph<br />

y<br />

(tonto),<br />

weather<br />

modeling<br />

(wrf2-AMR)<br />

SPEC Fl. Pt.:<br />

Ray tracer<br />

(povray)<br />

Machine<br />

Learning<br />

Belief<br />

propagatio<br />

n<br />

Expectatio<br />

n<br />

maximizati<br />

on<br />

Graphic<br />

s /<br />

Games<br />

Smoothin<br />

g;<br />

interpo<strong>la</strong>ti<br />

on<br />

Databas<br />

es<br />

MapReduc<br />

e<br />

Hashing Hashing<br />

<strong>Intel</strong> ®<br />

RMS<br />

Global<br />

illumination


242 Capitolo 7<br />

Dwarf Embedde<br />

d<br />

Computin<br />

g<br />

Convolution<br />

Encode<br />

9. Graph<br />

Traversal<br />

10. Dynamic<br />

Programmin<br />

g<br />

11. Backtrack<br />

and<br />

Branch<br />

+Bound<br />

12.<br />

Graphical<br />

Models<br />

13. Finite<br />

State<br />

Machine<br />

EEMBC<br />

Automotive:<br />

Pointer<br />

Chasing,<br />

Tooth to<br />

Spark;<br />

EEMBC<br />

Networking:<br />

IP NAT,<br />

OSPF,<br />

Route<br />

Lookup;<br />

EEMBC<br />

Office<br />

Automation:<br />

Text<br />

Processing;<br />

EEMBC<br />

Java: Chess,<br />

XML<br />

Parsing<br />

EEMBC<br />

Telecom:<br />

Viterbi<br />

Decode<br />

EEMBC<br />

Telecom:<br />

Viterbi<br />

Decode<br />

EEMBC<br />

Automotive:<br />

Angle To<br />

Time, Cache<br />

“Buster”,<br />

CAN<br />

Remote<br />

Data, PWM,<br />

Road Speed,<br />

Tooth to<br />

Spark;<br />

EEMBC<br />

General<br />

Purpose<br />

Computin<br />

g<br />

SPEC<br />

Integer: Go<br />

(gobmk)<br />

SPEC<br />

Integer:<br />

Chess (sjeng),<br />

network<br />

simplex<br />

algorithm<br />

(mcf), 2D<br />

path fin<strong>di</strong>ng<br />

library (astar)<br />

SPEC<br />

Integer:<br />

Hidden<br />

Markov<br />

models<br />

(hmmer)<br />

SPEC<br />

Integer: Text<br />

processing<br />

(perlbench),<br />

compression<br />

(bzip2),<br />

compiler<br />

(gcc), video<br />

compression<br />

(h264avc),<br />

network<br />

<strong>di</strong>screte event<br />

Machine<br />

Learning<br />

Bayesian<br />

networks,<br />

decision<br />

trees<br />

Forwardbackward,insideoutside,<br />

variable<br />

elimination<br />

, value<br />

iteration<br />

Kernel<br />

regression<br />

,<br />

constraint<br />

satisfactio<br />

n,<br />

satisficabili<br />

ty<br />

Hidden<br />

Markov<br />

models<br />

Graphic<br />

s /<br />

Games<br />

Reverse<br />

kinematic<br />

s,<br />

collision<br />

detection,<br />

depth<br />

sorting,<br />

hidden<br />

surface<br />

removal<br />

Response<br />

to<br />

collisions<br />

Databas<br />

es<br />

Transitive<br />

closure<br />

Query<br />

optimizatio<br />

n<br />

<strong>Intel</strong> ®<br />

RMS<br />

Natural<br />

<strong>la</strong>nguage<br />

processing


Le architetture del futuro 243<br />

Dwarf Embedde<br />

d<br />

Computin<br />

g<br />

Consumer:<br />

JPEG;<br />

EEMBC<br />

Digital<br />

Entertainme<br />

nt: Huffman<br />

Decode,<br />

MP3<br />

Decode,<br />

MPEG-2<br />

Decode,<br />

MPEG-2<br />

Encode,<br />

MPEG-4<br />

Decode;<br />

MPEG-4<br />

Encode;<br />

EEMBC<br />

Networking:<br />

QoS, TCP;<br />

EEMBC<br />

Office<br />

Automation:<br />

Text<br />

Processing;<br />

EEMBC<br />

Telecom: Bit<br />

Allocation;<br />

EEMBC<br />

Java: PNG<br />

General<br />

Purpose<br />

Computin<br />

g<br />

simu<strong>la</strong>tion<br />

(omnetpp),<br />

XML<br />

transformatio<br />

n<br />

(xa<strong>la</strong>ncbmk)<br />

Machine<br />

Learning<br />

Graphic<br />

s /<br />

Games<br />

Databas<br />

es<br />

<strong>Intel</strong> ®<br />

RMS<br />

Figura 7.7 - Mapping of EEMBC, SPEC2006, Machine Learning, Graphcs/Games,<br />

Data Base, and <strong>Intel</strong> ® ’s RMS to the 13 Dwarfs. *Note that SVM, QP, PDE:Face, and<br />

PDE:Cloth may use either dense or sparse matrices, depen<strong>di</strong>ng on the application.<br />

7.5 Autotuners<br />

La visione multi<strong>di</strong>sciplinare <strong>di</strong> Figura 7.5 è confermata e rafforzata da <strong>di</strong>versi<br />

esperimenti che hanno evidenziato <strong>la</strong> mutua <strong>di</strong>pendenza tra hardware e<br />

software.<br />

Ad esempio, pren<strong>di</strong>amo il caso del<strong>la</strong> ricerca in matrici sparse, memorizzate<br />

me<strong>di</strong>ante tecnica a blocchi. La <strong>di</strong>mensione <strong>di</strong> ciascun blocco è una caratteristica<br />

fondamentale su cui si basano le prestazioni dell’algoritmo <strong>di</strong> ricerca.


244 Capitolo 7<br />

Prendendo un processore <strong>Intel</strong> ® Itanium2 a 900 MHz si è valutato che <strong>la</strong><br />

<strong>di</strong>mensione ottimale del blocco è 4x2 (ve<strong>di</strong> Figura 7.8), <strong>di</strong>mensione non certo<br />

standard o preve<strong>di</strong>bile. Essendo questo problema al<strong>la</strong> base <strong>di</strong> numerosi<br />

algoritmi (e facente parte <strong>di</strong> uno <strong>dei</strong> “nani” descritti in precedenza) trovare una<br />

implementazione ottima è <strong>di</strong> grande interesse.<br />

Figura 7.8 – Prestazioni dell’Itanium 2 nel<strong>la</strong> ricerca in matrici sparse memorizzate<br />

me<strong>di</strong>ante tecnica a blocchi [4]<br />

Effettuando esperimenti su altre architetture, però, si è notato che tali<br />

<strong>di</strong>mensioni sono <strong>di</strong>fferenti (ve<strong>di</strong> Figura 7.9)


Le architetture del futuro 245<br />

row block size (r)<br />

8<br />

4<br />

2<br />

1<br />

Figura 7.9 – Dimensione <strong>dei</strong> Blocchi ottimizzate per <strong>di</strong>verse CPU nel<strong>la</strong> ricerca in<br />

matrici sparse [4]<br />

Il compi<strong>la</strong>tore non è quin<strong>di</strong> in grado senza conoscere <strong>la</strong> precisa architettura <strong>di</strong><br />

produrre un co<strong>di</strong>ce ottimizzato. Inoltre, produrre un co<strong>di</strong>ce ottimizzato su <strong>di</strong> una<br />

singo<strong>la</strong> architettura porta ad una cattiva portabilità del<strong>la</strong> applicazione, quin<strong>di</strong> ad<br />

un risultato tutt’altro che desiderato.<br />

La soluzione è quel<strong>la</strong> <strong>di</strong> spostare il problema dal compi<strong>la</strong>tore al<strong>la</strong> architettura.<br />

Deve essere a livello architetturale che si estraggono conoscenze sulle<br />

performance raggiungibili e si utilizzano le stesse per ottenere un co<strong>di</strong>ce<br />

ottimizzato.<br />

IBM Power 4,<br />

<strong>Intel</strong>/HP<br />

Itanium<br />

<strong>Intel</strong><br />

Pentium<br />

M<br />

<strong>Intel</strong>/HP<br />

Itanium 2<br />

IBM<br />

Power 3<br />

1 2 4 8<br />

column block size (c)<br />

Sun Ultra 2,<br />

Sun Ultra 3,<br />

AMD Opteron<br />

Si par<strong>la</strong> quin<strong>di</strong> <strong>di</strong> Auto-tuners, ovvero co<strong>di</strong>ci in grado <strong>di</strong> sperimentare al<strong>la</strong> prima<br />

esecuzione quali ottimizzazioni e quali parametri sono i migliori in base<br />

all’architettura su cui sono in esecuzione; successivamente tali ottimizzazioni<br />

devono essere riconosciute e mantenute. Co<strong>di</strong>ci autotuning richiedono però un


246 Capitolo 7<br />

supporto hardware e quin<strong>di</strong> le architetture future dovranno supportare in pieno<br />

tale tecnologia.<br />

7.6 Nuove metriche <strong>di</strong> valutazione<br />

La rivoluzione del pensiero comune descritta nel paragrafo 7.2 e <strong>la</strong> necessità <strong>di</strong><br />

multi<strong>di</strong>sciplinarità nel<strong>la</strong> progettazione delle architetture del futuro devono<br />

portare anche ad una nuova metrica <strong>di</strong> valutazione del<strong>la</strong> bontà delle nuove<br />

architetture. Valutazioni prettamente <strong>architetturali</strong>, o che riguardano so<strong>la</strong>mente<br />

il costo <strong>di</strong> produzione del solo processore non sono più sufficienti.<br />

Quali sono quin<strong>di</strong> le caratteristiche da tenere in considerazione?<br />

Innanzitutto è necessario massimizzare <strong>la</strong> produttività del programmatore.<br />

Avendo a <strong>di</strong>sposizione centinaia <strong>di</strong> unità <strong>di</strong> calcolo in un unico chip portano<br />

necessariamente ad una rivoluzione del<strong>la</strong> modalità <strong>di</strong> programmazione, nonché<br />

a nuove sfide per gli sviluppatori <strong>di</strong> software. La <strong>di</strong>fficoltà nel<strong>la</strong><br />

parallelizzazione delle applicazioni non è trascurabile.<br />

La possibilità <strong>di</strong> aumentare <strong>la</strong> produttività <strong>dei</strong> programmatori e l’effettiva<br />

usabilità delle mo<strong>di</strong>fiche <strong>architetturali</strong> implementate sono sicuramente da tenere<br />

in considerazione nel<strong>la</strong> valutazione <strong>dei</strong> nuovi <strong>processori</strong>.<br />

Inoltre non è da sottovalutare l’ipotesi <strong>di</strong> realizzare in hardware soluzioni ai<br />

problemi c<strong>la</strong>ssici del<strong>la</strong> programmazione attuale. Ad esempio, <strong>la</strong> realizzazione<br />

<strong>di</strong> un garbage collector per <strong>la</strong> gestione del<strong>la</strong> memoria <strong>di</strong>namica, <strong>la</strong> gestione delle<br />

fasi <strong>di</strong> debug, eccetera.


Le architetture del futuro 247<br />

Certamente <strong>la</strong> produttività è <strong>di</strong>fficilmente misurabile ma esistono comunque<br />

stu<strong>di</strong> come [50] e [51] che hanno cercato <strong>di</strong> valutare quantitativamente questo<br />

aspetto.<br />

Contemporaneamente, le nuove architetture dovranno cercare <strong>di</strong> massimizzare<br />

le prestazioni a livello <strong>di</strong> applicazione.<br />

<strong>Oltre</strong> a ciò, chiaramente rimangono vali<strong>di</strong> i parametri misurabili quali:<br />

minimizzazione del numero <strong>di</strong> accessi remoti<br />

bi<strong>la</strong>nciamento del carico<br />

livello <strong>di</strong> granu<strong>la</strong>rità dello scambio <strong>dei</strong> dati e del<strong>la</strong> sincronizzazione<br />

Per concludere, citiamo il progetto RAMP, che mira a stabilire una piattaforma<br />

con<strong>di</strong>visa e aperta per abilitare una rapida innovazione nel campo del software e<br />

delle architetture parallele [52].


Capitolo 8<br />

Conclusioni<br />

Da quanto illustrato nei capitoli precedenti, sia da un punto <strong>di</strong> vista teorico<br />

(ovvero nel Capitolo 2, nel Capitolo 3 e nel Capitolo 4), sia da un punto <strong>di</strong> vista<br />

applicativo (Capitolo 5 e Capitolo 6) appare abbastanza evidente come negli<br />

ultimi anni le mo<strong>di</strong>fiche sul singolo core delle CPU siano sempre meno<br />

significative. In partico<strong>la</strong>re sembrano sempre più vicini tre limiti (“Walls”, ve<strong>di</strong><br />

Capitolo 7):<br />

• Limiti imposti da requisiti <strong>di</strong> potenza <strong>di</strong>ssipata (Power Wall)<br />

• Limiti <strong>di</strong> parallelizzazione <strong>dei</strong> problemi (ILP Wall)<br />

• Limiti dovuti al “collo <strong>di</strong> bottiglia” delle memorie (Memory Wall)<br />

Questi problemi stringenti sembrano imporre, o comunque consigliare il<br />

passaggio al<strong>la</strong> tecnologia multicore che, si può <strong>di</strong>re, sia <strong>la</strong> “rivoluzione<br />

architetturale” più promettente degli ultimi anni e tuttora in via <strong>di</strong> sviluppo.<br />

Il <strong>di</strong>battito sul<strong>la</strong> sca<strong>la</strong>bilità delle architetture multicore rimane tuttavia aperto.<br />

Si par<strong>la</strong> infatti <strong>di</strong> <strong>di</strong>fferenza tra multicore e manycore, per <strong>di</strong>versificare le attuali<br />

architetture formate da pochi core (meno <strong>di</strong> 10) e quelle in cui il numero <strong>di</strong> core<br />

cresce in modo rilevante.


250 Capitolo 8<br />

Con<strong>di</strong>videndo <strong>la</strong> visione <strong>di</strong> Berkely, si auspica ben presto <strong>di</strong> poter passare da<br />

“tecnologie multicore” a “tecnologie manycore”, con migliaia <strong>di</strong> core per ogni<br />

processore.<br />

Lo sviluppo delle architetture future dovrà poi essere basato su stime valide dal<br />

punto <strong>di</strong> vista delle applicazioni del futuro, delineando correttamente e<br />

mantenendo aggiornata <strong>la</strong> cosiddetta lista “<strong>dei</strong> 7 nani”.<br />

Infine realizzare architetture “autotuners”, in grado <strong>di</strong> adattarsi al<strong>la</strong> partico<strong>la</strong>re<br />

applicazione e al<strong>la</strong> complessiva struttura del sistema, sarà sicuramente una<br />

scelta vincente.


Appen<strong>di</strong>ce A<br />

Storia del<strong>la</strong> <strong>Intel</strong> ® Corporation<br />

Figura A.1 - Gordon <strong>Moore</strong><br />

Nel 1968 Robert Noyce e Gordon <strong>Moore</strong><br />

<strong>la</strong>sciano <strong>la</strong> Fairchild Semiconductor e<br />

fondano <strong>la</strong> <strong>Intel</strong> ® . Il quarto <strong>di</strong>pendente fu<br />

Andrew "Andy" Grove, che <strong>di</strong>resse l’azienda<br />

dal suo arrivo negli anni Sessanta fino al suo<br />

pensionamento, avvenuto negli anni Novanta,<br />

facendo<strong>la</strong> <strong>di</strong>ventare una tra le più gran<strong>di</strong> multinazionali del mondo.<br />

<strong>Intel</strong> ® all’inizio produceva componenti per<br />

memorie e, durante gli anni settanta, era<br />

<strong>di</strong>venuta leader nel<strong>la</strong> produzione <strong>di</strong> memorie<br />

DRAM, SRAM e ROM. Da quando però nel<br />

1971 Marcian Hoff, Federico Faggin, Stanley<br />

Mazor e Masatoshi Shima inventarono il primo<br />

microprocessore, l’ <strong>Intel</strong> ® 4004, gradualmente<br />

fino agli anni ottanta <strong>la</strong> produzione si spostò verso quel<strong>la</strong> <strong>dei</strong> micro<strong>processori</strong><br />

facendo <strong>di</strong>ventare <strong>Intel</strong> ® una <strong>dei</strong> colossi in questo settore.<br />

Figura A.2 - Robert Noyce<br />

Nel 1983 toccò al presidente del<strong>la</strong> società, Andy Grove, trasformare <strong>la</strong><br />

produzione, abbandonando <strong>la</strong> costruzione <strong>di</strong> memorie per passare al<strong>la</strong>


252 Appen<strong>di</strong>ce A<br />

produzione <strong>di</strong> micro<strong>processori</strong>. Lo stesso Andy Grove descrisse questa<br />

transizione nel libro Only the Paranoid Survive. Un elemento chiave <strong>di</strong> questo<br />

processo fu sicuramente l’8086 che nel 1982 viene scelto per i PC IBM al<strong>la</strong><br />

con<strong>di</strong>zione (imposta da IBM) <strong>di</strong> avere una seconda fonte <strong>di</strong> produzione. La<br />

seconda fonte sarà AMD ® , che con uno scambio <strong>di</strong> licenze <strong>di</strong>viene il secondo<br />

fornitore <strong>di</strong> <strong>processori</strong> 8088 e 8086 per i PC IBM. Il "problema" <strong>dei</strong> secon<strong>di</strong><br />

fornitori sarà sempre presente fino all’avvento del Pentium.<br />

Durante gli anni novanta <strong>la</strong> <strong>Intel</strong> ® Architecture Labs (IAL) fu <strong>la</strong> maggior<br />

responsabile delle innovazioni hardware <strong>dei</strong> personal computer, fra cui il bus<br />

PCI, il bus PCI Express, l’Universal Serial Bus (USB) e le prime architetture<br />

per server multi<strong>processori</strong> (SMP).<br />

Il controllo totale del mercato <strong>dei</strong> <strong>processori</strong> x86 procurò all’ <strong>Intel</strong> ® negli anni<br />

molte cause da parte dell’Antitrust. Attualmente <strong>Intel</strong> ® control<strong>la</strong> l’85% del<br />

mercato <strong>dei</strong> <strong>processori</strong> 32-bit, unico suo avversario è <strong>la</strong> Advanced Micro<br />

Devices con cui <strong>Intel</strong> ® ha un accordo dal 1976: ognuna delle due major può<br />

usare le tecnologie brevettate dall’avversario senza dover richiederne il<br />

consenso.<br />

<strong>Intel</strong> ® attualmente produce micro<strong>processori</strong>, componenti <strong>di</strong> rete, chipset per<br />

motherboard (scheda madre), chip per schede video e molti altri circuiti<br />

integrati.


Storia del<strong>la</strong> <strong>Intel</strong>® Corporation 253<br />

Nel settembre del 2007 <strong>la</strong> società ha acquisito Havok, sviluppatore noto in<br />

ambito software per lo sviluppo dell’omonimo motore fisico utilizzato in più <strong>di</strong><br />

150 videogiochi. Nell’ottobre dello stesso anno ha raggiunto un accordo<br />

extragiu<strong>di</strong>ziario con Transmeta: <strong>la</strong> società accusava <strong>Intel</strong> ® <strong>di</strong> aver vio<strong>la</strong>to alcune<br />

suo proprietà <strong>Intel</strong>lettuali. <strong>Intel</strong> ® ha pagato 250 milioni <strong>di</strong> dol<strong>la</strong>ri per aver<br />

accesso non esclusivo a tutti i brevetti del<strong>la</strong> società. Nel febbraio del 2008 <strong>la</strong><br />

società è stata citata in giu<strong>di</strong>zio dall’University of Wisconsin - Ma<strong>di</strong>son per<br />

aver vio<strong>la</strong>to il brevetto statunitense 5.781.752 nei <strong>processori</strong> Core 2.<br />

SCHEDA:<br />

Nazione Stati Uniti<br />

Tipologia Public company<br />

Fondazione: 1968<br />

Fondata da: Gordon <strong>Moore</strong> e Robert Noyce<br />

Sede principale Santa C<strong>la</strong>ra (California), USA<br />

Persone chiave Paul Otellini, CEO e Craig Barrett,<br />

Chairman<br />

Fatturato: 31,5 miliar<strong>di</strong> $ (2006)<br />

Utile netto: 5 miliar<strong>di</strong> $ (2006)<br />

Dipendenti: 94.000<br />

Slogan: “Leap Ahead”<br />

Sito web www. <strong>Intel</strong> ® .com


254 Appen<strong>di</strong>ce A<br />

LISTA DEI PROCESSORI INTEL ®<br />

Famiglia 4 bit/8 bit: 4004 | 4040 | 8008 | 8080 | 8085<br />

Famiglia 16 bit: 8086 | 8088 | 80186 | 80286<br />

Famiglia IA-32: 80386 | 80486<br />

Gamma Pentium: Pentium ® | Pentium ® Pro | Pentium ® II |<br />

Celeron | Pentium ® III | Pentium ® III-<br />

M | Pentium ® 4 | Pentium ® 4-M |<br />

Mobile Pentium ® 4 | Pentium ® 4 EE |<br />

Celeron D | Pentium ® D | Pentium ® EE<br />

Processori Mobile: Pentium ® M | Celeron M | Core Duo |<br />

Core Solo<br />

Gamma Core: Core 2 Duo | Core 2 Quad | Core 2<br />

Extreme<br />

Gamma Nehalem: Core i5 | Core i7 | Core i7 Extreme<br />

Processori per Server: Xeon<br />

Famiglia IA-64: Itanium | Itanium 2<br />

Non x86 compatibili: <strong>Intel</strong> ® iAPX 432 | <strong>Intel</strong> ® i860 | <strong>Intel</strong> ®<br />

i960


Appen<strong>di</strong>ce B<br />

Storia <strong>dei</strong> <strong>processori</strong> <strong>Intel</strong> ®<br />

Cenni sul<strong>la</strong> evoluzione <strong>dei</strong> <strong>processori</strong> <strong>Intel</strong> ® precedenti al<br />

Pentium<br />

1971: MICROPROCESSORE 4004<br />

Il primo microprocessore per uso generico<br />

nasce da un’intuizione: quando <strong>la</strong> Busicom,<br />

produttrice giapponese <strong>di</strong> calco<strong>la</strong>trici,<br />

or<strong>di</strong>na al<strong>la</strong> <strong>Intel</strong> ® <strong>la</strong> produzione <strong>di</strong> un set <strong>di</strong><br />

do<strong>di</strong>ci chip <strong>di</strong> <strong>di</strong>fferenti tipologie,<br />

l’ingegnere Ted Hoff pensò <strong>di</strong> incorporare<br />

in un unico microprocessore tutte le<br />

funzioni del set.<br />

Nasce il primo <strong>di</strong>spositivo programmabile e<br />

control<strong>la</strong>bile tramite un linguaggio <strong>di</strong> programmazione in grado <strong>di</strong> sod<strong>di</strong>sfare le<br />

necessità <strong>di</strong> e<strong>la</strong>borazione più <strong>di</strong>sparate. Il 4004 era dotato <strong>di</strong> registri capaci <strong>di</strong><br />

gestire 4 bit al<strong>la</strong> volta.


256 Appen<strong>di</strong>ce B<br />

1972: MICROPROCESSORE 8008<br />

Il 4004 era in grado <strong>di</strong> operare esclusivamente con cifre numeriche, ma per<br />

generalizzare l’uso del processore era<br />

necessario aumentare le <strong>di</strong>mensioni <strong>dei</strong><br />

registri per poter trattare tutti i caratteri<br />

alfanumerici e <strong>di</strong> punteggiatura. Con sei bit<br />

era possibile rappresentare tutti i caratteri<br />

alfanumerici, ma non i vari caratteri <strong>di</strong><br />

punteggiatura. L’emergere contemporaneo<br />

del byte a otto bit quale standard <strong>di</strong><br />

co<strong>di</strong>fica <strong>dei</strong> dati <strong>di</strong>gitali favorì <strong>la</strong> scelta <strong>di</strong><br />

questo formato quale <strong>di</strong>mensione del registro del nuovo microprocessore.<br />

L’8008 a otto bit fu protagonista <strong>dei</strong> primi tentativi <strong>di</strong> costruzione <strong>di</strong><br />

microcomputer: secondo <strong>la</strong> rivista Ra<strong>di</strong>o Electronics un hobbista <strong>di</strong> informatica,<br />

Don Lancaster, utilizzò l’8008 per creare un predecessore del primo personal<br />

computer, un <strong>di</strong>spositivo che Ra<strong>di</strong>o Electronics soprannominò "macchina per<br />

scrivere con TV".<br />

1974: MICROPROCESSORE 8080<br />

Il processore 8080, versione migliorata del 8008 in grado <strong>di</strong> gestire un numero<br />

maggiore <strong>di</strong> istruzioni, <strong>di</strong>ventò il cervello del primo personal computer, l’Altair.<br />

Gli hobbisti <strong>di</strong> informatica potevano acquistare un kit per l’Altair al prezzo <strong>di</strong><br />

395 dol<strong>la</strong>ri. In pochi mesi, ne furono vendute decine <strong>di</strong> migliaia, dando luogo ai<br />

primi arretrati <strong>di</strong> or<strong>di</strong>nativi <strong>di</strong> PC nel<strong>la</strong> storia.


Storia <strong>dei</strong> <strong>processori</strong> <strong>Intel</strong>® 257<br />

A questo punto alcuni col<strong>la</strong>boratori<br />

<strong>di</strong> Hoff <strong>la</strong>sciarono <strong>la</strong> <strong>Intel</strong> ® per<br />

fondare <strong>la</strong> compagnia Zilog<br />

Corporation, che produsse<br />

un’ulteriore evoluzione dell’8080:<br />

lo Z80.<br />

<strong>Intel</strong> ® nel frattempo realizzò<br />

l’8085, stu<strong>di</strong>ato per funzionare con<br />

un’unica alimentazione a 5 volt. Si entra nel<strong>la</strong> seconda generazione. La sua<br />

architettura, ancora oggi oggetto <strong>di</strong> stu<strong>di</strong>o nelle università, prevedeva <strong>la</strong><br />

presenza <strong>di</strong> unità <strong>di</strong> input/output e <strong>la</strong> capacità <strong>di</strong> gestire le interruzioni a livello<br />

<strong>di</strong> vettori.<br />

1978: MICROPROCESSORE 8086<br />

Appartiene al<strong>la</strong> terza generazione <strong>di</strong> micro<strong>processori</strong>: <strong>la</strong> <strong>di</strong>mensione <strong>dei</strong> registri<br />

raddoppia ulteriormente e si entra nell’era <strong>dei</strong> 16 bit. Il guadagno in termini <strong>di</strong><br />

prestazioni risulta essere così <strong>di</strong>eci volte maggiore rispetto a quello dell’8080.<br />

Attraverso un bus <strong>dei</strong> dati <strong>di</strong> 20 bit è in grado <strong>di</strong> in<strong>di</strong>rizzare <strong>di</strong>rettamente un Mb<br />

<strong>di</strong> memoria, una quantità pressoché infinita per quei tempi.<br />

La novità apportata dal processore era l’utilizzo del<strong>la</strong> memoria in modo<br />

segmentato. Attraverso questo metodo si definisce <strong>la</strong> memoria in segmenti e il<br />

processore vi accede me<strong>di</strong>ante il formato seg:<strong>di</strong>sp, dove il valore <strong>di</strong> seg è<br />

collegato al<strong>la</strong> posizione <strong>di</strong> memoria fisica in cui ha inizio il segmento, mentre il<br />

valore <strong>di</strong>sp in<strong>di</strong>ca il <strong>di</strong>sp<strong>la</strong>cement del<strong>la</strong> suddetta posizione <strong>di</strong> memoria all’inizio


258 Appen<strong>di</strong>ce B<br />

del segmento precedente. Per chiarire con un esempio, <strong>la</strong> <strong>di</strong>stanza 4500 metri<br />

può essere espressa nel valore assoluto 4500 o con <strong>la</strong> notazione 4:500, in cui 4<br />

sarebbe <strong>la</strong> <strong>di</strong>stanza in chilometri, mentre 500 sarebbero i metri a partire dal<br />

quarto chilometro. Allo stesso modo, un in<strong>di</strong>rizzo fisico può essere definito<br />

dall’in<strong>di</strong>rizzo <strong>di</strong> inizio del segmento + il re<strong>la</strong>tivo <strong>di</strong>sp<strong>la</strong>cement. Questo metodo<br />

permette <strong>di</strong> supportare <strong>la</strong> rilocazione <strong>dei</strong> programmi, ovvero <strong>la</strong> possibilità che<br />

un programma possa essere eseguito in un qualunque segmento o zona <strong>di</strong><br />

memoria, senza fare altro che cambiare il valore del registro del segmento.<br />

1979: MICROPROCESSORE 8088<br />

Rappresenta un passo in<strong>di</strong>etro<br />

nell’evoluzione: mantiene il set <strong>di</strong><br />

istruzioni e le <strong>di</strong>mensioni <strong>dei</strong><br />

registri dell’8086, ma il bus <strong>dei</strong><br />

dati è ridotto a otto bit, contro i<br />

se<strong>di</strong>ci del processore precedente.<br />

Questa operazione è stata fatta per<br />

rendere l’8088 compatibile con<br />

gli adattatori hardware in<br />

commercio e per poter impiegare chip <strong>di</strong> supporto economici e facilmente<br />

reperibili nei primi personal computer.<br />

Il processore 8088 <strong>di</strong>ventò quin<strong>di</strong> il cervello del nuovo prodotto <strong>di</strong> punta<br />

dell’IBM: l’IBM PC. La struttura a 16 bit pose il personal <strong>di</strong> Big Blue in<br />

posizione <strong>di</strong> vantaggio rispetto agli altri microcomputer, completamente a otto


Storia <strong>dei</strong> <strong>processori</strong> <strong>Intel</strong>® 259<br />

bit. Più tar<strong>di</strong> l’IBM realizzerà <strong>la</strong> linea <strong>di</strong> personal PS/2, basata sul più potente<br />

processore 8086.<br />

Il successo del processore 8088 comportò l’inserimento <strong>di</strong> <strong>Intel</strong> ® nelle<br />

c<strong>la</strong>ssifiche <strong>di</strong> Fortune 500, e <strong>la</strong> rivista Fortune definì questa società uno <strong>dei</strong><br />

trionfi aziendali degli anni settanta.<br />

Il passaggio dai micro<strong>processori</strong> a 8 bit ai micro<strong>processori</strong> a 16 bit non va<br />

so<strong>la</strong>mente visto come un’evoluzione quantitativa delle potenzialità <strong>dei</strong><br />

micro<strong>processori</strong> ma come evoluzione qualitativa nel tentativo <strong>di</strong> ricreare le<br />

potenzialità <strong>dei</strong> primi minicomputer e mainframe in un personal computer.<br />

Le limitazioni <strong>di</strong> un processore a 8 bit erano del resto chiarissime, non potendo<br />

questo gestire, se non con innaturali paginazioni, memorie superiori a 64 K ed<br />

era limitato dal<strong>la</strong> <strong>di</strong>mensione <strong>dei</strong> suoi registri nell’esecuzione <strong>di</strong> operazioni su<br />

insiemi <strong>di</strong> dati complessi, in special modo nell’ambio delle operazioni<br />

matematiche.<br />

1982: MICROPROCESSORE 80286<br />

Dopo l’80186 e l’80188, venne<br />

commercializzato nel tardo 1982 il<br />

processore 286, che rappresentò una<br />

vera e propria rivoluzione nel mondo<br />

personal. Fu il primo processore<br />

completamente a 16 bit, in grado cioè<br />

<strong>di</strong> accedere a due byte <strong>di</strong> memoria


260 Appen<strong>di</strong>ce B<br />

consecutivi in un’unica operazione.<br />

Tra le nuove caratteristiche, cinque nuovi registri per <strong>la</strong> gestione del<strong>la</strong> memoria<br />

in modalità multitasking e <strong>la</strong> possibilità, per mantenere <strong>la</strong> compatibilità verso il<br />

basso, <strong>di</strong> poter <strong>la</strong>vorare in modalità reale o protetta. Nel<strong>la</strong> prima modalità si<br />

comporta come l’8086 e non utilizza i nuovi registri: è compatibile con il suo<br />

predecessore, col vantaggio <strong>di</strong> essere molto più veloce. Nel<strong>la</strong> modalità protetta<br />

consente il multitasking e <strong>la</strong> protezione tra task e memoria virtuale. La modalità<br />

protetta non ebbe inizialmente successo: le applicazioni per 8086 esistenti non<br />

erano compatibili e solo nel 1987 verrà sviluppato l’OS/2, un sistema operativo<br />

in grado <strong>di</strong> operare in modalità protetta.<br />

La frequenza <strong>di</strong> clock inizialmente era <strong>di</strong> 6 MHz, <strong>di</strong>venne presto otto, quin<strong>di</strong><br />

<strong>di</strong>eci e poi 12 nel 1984. Negli anni successivi, usciranno versioni a 16 e persino<br />

a 20 MHz.<br />

Secondo alcune stime, entro 6 anni dall’introduzione del processore 286, i<br />

personal computer basati su questo processore erano 15 milioni in tutto il<br />

mondo. Con il 286, il PC esce dal<strong>la</strong> categoria <strong>dei</strong> sistemi batch (sistemi che<br />

eseguono vari <strong>la</strong>vori in sequenza) per entrare a fare parte <strong>dei</strong> sistemi<br />

multitasking (sistemi nei quali i processi possono avanzare in parallelo).<br />

1985: MICROPROCESSORE 80386<br />

Con questo processore si realizza un ulteriore passo avanti: raddoppiano <strong>la</strong><br />

<strong>di</strong>mensione <strong>dei</strong> registri e del bus <strong>dei</strong> dati, portati a 32 bit reali. Questo fa sì che<br />

si possano eseguire istruzioni con numeri maggiori come operan<strong>di</strong>.


Storia <strong>dei</strong> <strong>processori</strong> <strong>Intel</strong>® 261<br />

E’ in grado <strong>di</strong> eseguire tutte le<br />

istruzioni <strong>dei</strong> chip precedenti, ma<br />

li sorpassa in termini <strong>di</strong><br />

prestazioni. I primi chip<br />

operavano a frequenze <strong>di</strong> 12,5 e<br />

16 MHz; nel tardo 1986 venne<br />

commercializzata <strong>la</strong> versione a<br />

20 MHz, seguita due anni dopo<br />

da quel<strong>la</strong> a 25 MHz. Nel 1989 arrivarono i "mostri" a 33 MHz.<br />

L’80386 può <strong>la</strong>vorare in tre <strong>di</strong>fferenti modalità: reale, protetta e virtuale 86.<br />

Nel<strong>la</strong> prima modalità <strong>la</strong>vora come un 8086, ma è decisamente più veloce. In<br />

modalità protetta <strong>la</strong>vora come l’80286, consentendo il multitasking, <strong>la</strong><br />

protezione e <strong>la</strong> gestione del<strong>la</strong> memoria virtuale, consentendo però anche <strong>la</strong><br />

paginazione. Per ridurre <strong>la</strong> frammentazione in memoria e per poter allocare<br />

processi che non potrebbero essere caricati a meno <strong>di</strong> non ricorrere al<strong>la</strong><br />

riconfigurazione del<strong>la</strong> memoria, si sud<strong>di</strong>vide <strong>la</strong> memoria centrale in pagine,<br />

nelle quali allocare le parti logiche del processo. Le pagine sono <strong>di</strong> <strong>di</strong>mensioni<br />

fisse, ad esempio 4 K o una qualche potenza del 2. La modalità virtuale 86<br />

permette <strong>di</strong> inizializzare un numero indefinito <strong>di</strong> macchine virtuali in<br />

esecuzione in modalità reale, assegnando a ciascun processo 1 Mb <strong>di</strong> memoria e<br />

una copia del DOS, come se si trattasse <strong>di</strong> un e<strong>la</strong>boratore 8086. Ogni macchina<br />

virtuale è in grado <strong>di</strong> gestire autonomamente un applicativo, mantenendolo<br />

iso<strong>la</strong>to dalle altre istanze. In questo modo, un programma viene eseguito come


262 Appen<strong>di</strong>ce B<br />

accadrebbe con l’8086, ma senza perdere i vantaggi del<strong>la</strong> modalità protetta:<br />

anche se un processo si blocca, rimangono attivi il multitasking e i meccanismi<br />

<strong>di</strong> protezione e non si ferma tutto l’e<strong>la</strong>boratore.<br />

Gli analisti avevano previsto che il processore non avrebbe avuto un mercato <strong>di</strong><br />

<strong>la</strong>rgo consumo e ne prevedevano un uso limitato ad architetti e scienziati. Per<br />

sod<strong>di</strong>sfare l’utenza, non <strong>di</strong>sposta a pagare l’alto prezzo del processore, che in<br />

Italia nel 1984 costava circa 800 mi<strong>la</strong> lire, l’ <strong>Intel</strong> ® commercializzerà dal 1988<br />

<strong>la</strong> serie 80386sx, con un clock interno a 16 bit, come gli 8086.<br />

Successivamente, <strong>la</strong> versione originale dell’80386 verrà commercializzata con<br />

<strong>la</strong> sig<strong>la</strong> dx.<br />

1989: MICROPROCESSORE 80486<br />

E’ un 80386 al quale viene affiancato, in<br />

un unico chip, il coprocessore 80387, dato<br />

che integra al suo interno molte <strong>di</strong> quelle<br />

parti che erano considerate moduli<br />

aggiuntivi nei micro<strong>processori</strong> precedenti;<br />

moduli come il coprocessore matematico,<br />

appunto, o come <strong>la</strong> memoria cache.<br />

L’ <strong>Intel</strong> ® , pur tenendo in considerazione <strong>la</strong><br />

compatibilità con i <strong>processori</strong> precedenti,<br />

mo<strong>di</strong>fica <strong>legge</strong>rmente l’architettura e per<br />

<strong>la</strong> prima volta implementa delle routine Risc nel<strong>la</strong> progettazione, ottenendo una<br />

<strong>di</strong>minuzione del tempo <strong>di</strong> esecuzione delle singole istruzioni a parità <strong>di</strong>


Storia <strong>dei</strong> <strong>processori</strong> <strong>Intel</strong>® 263<br />

frequenza <strong>di</strong> clock. Inoltre, <strong>la</strong> nuova tecnologia costruttiva permette <strong>di</strong><br />

realizzare le comunicazioni verso l’esterno a 33 MHz evitando problemi <strong>di</strong><br />

compatibilità con circuiterie non modernissime, mentre <strong>la</strong> velocità interna <strong>di</strong><br />

e<strong>la</strong>borazione è <strong>di</strong> 66 MHz.<br />

Grazie al<strong>la</strong> <strong>di</strong>fferente tecnologia, a parità <strong>di</strong> clock ha prestazioni da due a tre<br />

volte superiori rispetto a quelle dell’80386 e nel coprocessore matematico c’è<br />

un aumento delle prestazioni superiore al cinquanta per cento.<br />

Il processore originale <strong>la</strong>vorava a 25 MHz, ma anche per il 486 venne adottata<br />

<strong>la</strong> stessa strategia per il processore precedente: un paio <strong>di</strong> anni più tar<strong>di</strong> uscì una<br />

versione senza coprocessore matematico (80486sx), meno potente ma meno<br />

costosa. La versione 80486dx aveva una frequenza <strong>di</strong> 33 MHz, seguita in poco<br />

tempo dall’80486 dx2 (con clock a 50 MHz) e dal<strong>la</strong> versione a 66 MHz. Anche<br />

con il sopraggiungere del<strong>la</strong> tecnologia Pentium ® , <strong>la</strong> <strong>Intel</strong> ® continuò <strong>la</strong><br />

produzione <strong>dei</strong> chip 486, giungendo nel 1995 al<strong>la</strong> versione 80486dx4 con clock<br />

a 100 MHz, in grado <strong>di</strong> rivaleggiare con un Pentium ® a 66 MHz.<br />

La tabel<strong>la</strong> seguente riassume le caratteristiche principali <strong>dei</strong> modelli appena<br />

trattati.<br />

Processore<br />

Dimensione<br />

registri<br />

Linee<br />

bus<br />

dati<br />

Linee<br />

bus<br />

in<strong>di</strong>rizzi<br />

Memoria<br />

in<strong>di</strong>rizzabile<br />

8088 16 bit 8 20 1 Mb 8087<br />

8086 16 bit 16 20 1 Mb 8087<br />

Coprocessore<br />

richiesto


264 Appen<strong>di</strong>ce B<br />

Processore<br />

Dimensione<br />

registri<br />

Linee<br />

bus<br />

dati<br />

Linee<br />

bus<br />

in<strong>di</strong>rizzi<br />

Memoria<br />

in<strong>di</strong>rizzabile<br />

80286 16 bit 16 24 16 Mb 80287<br />

80386SX 32 bit 16 24 16 Mb 80387<br />

80386DX 32 bit 32 32 4 Gb 80387<br />

80486SX 32 bit 32 32 4 Gb 80387<br />

Coprocessore<br />

richiesto<br />

80486 32 bit 32 32 4 Gb Incorporato


Storia <strong>dei</strong> <strong>processori</strong> <strong>Intel</strong>® 265<br />

Evoluzione <strong>dei</strong> <strong>processori</strong> <strong>Intel</strong> ® a partire dal Pentium<br />

1993: PROCESSORE PENTIUM<br />

Le caratteristiche principali sono rappresentate dal<strong>la</strong> presenza <strong>di</strong> registri a 64<br />

bit, dal<strong>la</strong> capacità <strong>di</strong> eseguire più <strong>di</strong> una istruzione per clock, dal<strong>la</strong> notevole<br />

presenza del coprocessore matematico. Il processore, cinque volte più potente <strong>di</strong><br />

un 486 a 25 MHz, incorpora una tecnologia che permette <strong>di</strong> miniaturizzare in un<br />

solo chip ben 3,1 milioni <strong>di</strong> transistor, rispetto al milione utilizzato nel 486.<br />

Il Pentium ® è dotato <strong>di</strong> due cache aggiuntive da 8 Kb, una per il co<strong>di</strong>ce e una<br />

per i dati. La doppia cache incorporata rende il processore più efficiente<br />

nell’e<strong>la</strong>borazione.<br />

La pre<strong>di</strong>sposizione alle operazioni <strong>di</strong> risparmio energetico permette <strong>di</strong><br />

razionalizzare il consumo elettrico e <strong>di</strong> aggiungere ulteriori funzioni <strong>di</strong><br />

sicurezza.


266 Appen<strong>di</strong>ce B<br />

Nel 1994 viene introdotto il Pentium ® a 90 MHz, che funziona a 3,3 volt<br />

anziché a cinque tipici delle CPU 80x86. L’anno successivo escono processore<br />

con frequenze a clock 75, 90 e 100 MHz. A <strong>di</strong>stanza <strong>di</strong> poco tempo, le CPU<br />

arrivano ad una capacità <strong>di</strong> e<strong>la</strong>borazione a 120 e 133 MHz, mentre nel 1996<br />

escono i modelli a 150, 166 e 200 MHz. Nel 1994, un insegnante universitario<br />

scopre che il Pentium ® genera in certe situazioni risultati errati nei calcoli in<br />

virgo<strong>la</strong> mobile.<br />

1995: PROCESSORE PENTIUM ® PRO<br />

Presentato nell’autunno del 1995, il processore Pentium ® Pro è stato progettato<br />

per potenziare le applicazioni a 32 bit a livello <strong>di</strong> workstation e <strong>di</strong> server, in<br />

quanto consente <strong>di</strong> effettuare operazioni veloci <strong>di</strong> CAD, ingegneria meccanica e<br />

calcolo scientifico. Ogni processore Pentium ® Pro viene fornito insieme ad un<br />

secondo chip <strong>di</strong> memoria cache per il potenziamento del<strong>la</strong> velocità. Il potente


Storia <strong>dei</strong> <strong>processori</strong> <strong>Intel</strong>® 267<br />

processore Pentium ® Pro vanta 5,5 milioni <strong>di</strong> transistor; <strong>la</strong> velocità minima <strong>dei</strong><br />

modelli é <strong>di</strong> 150 MHz.<br />

1997: PROCESSORE PENTIUM ® II<br />

Costruito con <strong>la</strong> tecnologia a 0,35 micron (<strong>la</strong> <strong>di</strong>mensione<br />

massima <strong>di</strong> un singolo transistor nel processore), il<br />

processore Pentium ® II conta 7,5 milioni <strong>di</strong> transistor.<br />

Incorpora <strong>la</strong> tecnologia MMX <strong>di</strong> <strong>Intel</strong> ® , progettata<br />

specificamente per l’e<strong>la</strong>borazione efficiente <strong>di</strong> dati video, au<strong>di</strong>o e grafici. Viene<br />

fornito con un chip <strong>di</strong> memoria cache ad alta velocità in una innovativa<br />

cartuccia S.E.C. (Single Edge Contact), collegata<br />

al<strong>la</strong> scheda madre tramite un connettore che presenta<br />

una singo<strong>la</strong> estremità anziché una serie <strong>di</strong> pin.<br />

Il bus <strong>di</strong> sistema è passato dai 66 MHz, per le versioni con frequenze dai 233 ai<br />

333 MHz, ai 100 MHz per versioni fino ai 450 MHz. Il Pentium ® II raggiunge <strong>la</strong><br />

velocità <strong>di</strong> 450 MHz nell’estate 1998.<br />

Le prime versioni del processore, nome in co<strong>di</strong>ce K<strong>la</strong>math, sono state prodotte<br />

con <strong>la</strong> tecnologia a 0,35 micron. Gli ultimi modelli del Pentium ® II (con<br />

frequenze superiori ai 333 MHz), nome in co<strong>di</strong>ce Deschutes, sono stati prodotti<br />

con <strong>la</strong> tecnologia a 0,25 micron. Il Deschutes consente così, grazie alle ridotte<br />

<strong>di</strong>mensioni, un minore consumo energetico, minore surriscaldamento e quin<strong>di</strong><br />

maggiore velocità. Esistono due versioni <strong>di</strong> Deschutes per portatili, a 300 e 366<br />

MHz.


268 Appen<strong>di</strong>ce B<br />

L’introduzione del Pentium ® II ha comportato però <strong>la</strong> drastica mo<strong>di</strong>fica del<strong>la</strong><br />

struttura delle schede madri, che devono essere in grado <strong>di</strong> ospitare<br />

l’alloggiamento del processore: uno slot invece del c<strong>la</strong>ssico zoccolo, e i nuovi<br />

moduli per <strong>la</strong> memoria RAM, da 72 contatti (Simm) ai <strong>di</strong>eci volte più veloci<br />

moduli a 168 contatti (Dimm).<br />

1997: PROCESSORE PENTIUM ® III<br />

La prima versione <strong>di</strong> Pentium ® III, chiamata Katmai,<br />

era in pratica un Pentium ® II costruito con un<br />

processo a 250 nm, con l’aggiunta delle istruzioni<br />

SSE ed un migliorato controllo del<strong>la</strong> memoria cache<br />

L2 da 512 KB. Fu inizialmente <strong>di</strong>ffuso a velocità <strong>di</strong><br />

450 MHz e 500 MHz con BUS a 100 MHz. Katmai utilizzava inoltre lo stesso<br />

involucro a slot del Pentium ® II, lo Slot 1.<br />

La seconda versione, Coppermine, costruita a 180 nm, aveva una memoria<br />

cache L2 ridotta a 256 KB ma integrata a piena velocità, caratteristica che<br />

migliorò le prestazioni rispetto a Katmai. Messa sotto pressione dal<strong>la</strong> valida<br />

concorrenza <strong>di</strong> AMD ® col suo Athlon C<strong>la</strong>ssic, <strong>Intel</strong> ® aveva riprogettato il chip<br />

internamente, e rime<strong>di</strong>ato agli ormai noti stalli nel<strong>la</strong> pipeline. Il risultato fu un<br />

miglioramento del 30% nell’esecuzione delle istruzioni. Le frequenze salirono<br />

velocemente, dagli originari 733 Mhz al GHz e a metà del 2000 <strong>Intel</strong> ® <strong>la</strong>nciò<br />

una versione a 1,13 GHz, ma un popo<strong>la</strong>re sito <strong>di</strong> hardware provò in una<br />

recensione che questa non era abbastanza stabile da far girare il kernel Linux. Il<br />

problema fu identificato nel<strong>la</strong> cache integrata, che non poteva essere cloccata a


Storia <strong>dei</strong> <strong>processori</strong> <strong>Intel</strong>® 269<br />

velocità oltre il GHz. <strong>Intel</strong> ® impiegò sei mesi per risolvere il problema e infine<br />

ri<strong>la</strong>sciò le versioni a 1,1 e 1,13 GHz nel 2001.<br />

2000: PROCESSORE PENTIUM ® IV<br />

GHz e 1,5 GHz<br />

Il Pentium ® 4 è un microprocessore x86 <strong>di</strong> settima<br />

generazione prodotto da <strong>Intel</strong> ® , ed è il primo design<br />

originale <strong>di</strong> quest’ultima dai tempi del Pentium ® Pro, nel<br />

1995. Il processore originale, chiamato Wil<strong>la</strong>mette, fu<br />

<strong>la</strong>nciato il 20 novembre del 2000 con frequenze <strong>di</strong> 1,4<br />

A partire dal Pentium ® Pro, si erano succeduti <strong>processori</strong> basati sull’architettura<br />

"P6", con marginali miglioramenti (il Pentium ® II, il Pentium ® III, ed i vari<br />

Celeron); il Pentium ® 4 invece si basa sul<strong>la</strong> nuova architettura NetBurst. Inoltre<br />

fu introdotto un velocissimo FSB a 400 MHz, formato in realtà da quattro bus a<br />

100 MHz; tuttavia <strong>la</strong> <strong>la</strong>rghezza <strong>di</strong> banda era pari a quattro volte quelle <strong>di</strong> un bus<br />

a 100 MHz, e fu così considerato come un unico bus a 400 MHz (il competitore<br />

più veloce non andava oltre i 133 MHz effettivi).<br />

Per <strong>la</strong> sorpresa <strong>di</strong> molti tecnici del settore, il nuovo processore non migliorava il<br />

design P6 né nel calcolo intero, né in virgo<strong>la</strong> mobile, generalmente considerati i<br />

fattori chiave nelle prestazioni <strong>di</strong> un processore. Furono sacrificate le<br />

prestazioni nel singolo ciclo <strong>di</strong> clock per guadagnare su due fronti: nel<strong>la</strong><br />

massima frequenza raggiungibile, e nelle prestazioni sfruttando le nuove librerie<br />

SSE2 che andavano ad aggiungersi alle precedenti SSE ed MMX.


270 Appen<strong>di</strong>ce B<br />

Il Pentium ® 4 "svolge molto meno <strong>la</strong>voro" in ogni ciclo <strong>di</strong> clock rispetto ad altre<br />

CPU (come ad esempio i vari AMD ® Athlon o i vecchi Pentium ® III), ma<br />

l’obiettivo iniziale <strong>di</strong> sacrificare le prestazioni sul singolo ciclo <strong>di</strong> clock era<br />

bi<strong>la</strong>nciato dal<strong>la</strong> possibilità <strong>di</strong> aumentare molto velocemente <strong>la</strong> frequenza <strong>di</strong><br />

funzionamento, caratteristica che portava comunque a ottime prestazioni<br />

paragonabili a quelle <strong>dei</strong> <strong>processori</strong> del<strong>la</strong> rivale AMD ® , pur seguendo una<br />

strategia <strong>di</strong>versa. Tutto questo è andato avanti fino a quando il processore ha<br />

trovato problemi insolubili <strong>di</strong> eccessiva produzione <strong>di</strong> calore, poco prima <strong>di</strong><br />

raggiungere i 4 GHz (fermandosi effettivamente a 3.8 GHz con il core Prescott),<br />

molto lontano dagli annunci entusiastici del <strong>la</strong>ncio che par<strong>la</strong>vano <strong>di</strong> sca<strong>la</strong>bilità<br />

fino a 10 GHz.<br />

Al<strong>la</strong> metà del 2005, resasi conto che ormai <strong>la</strong> "corsa ai GHz" era finita, <strong>la</strong> casa<br />

produttrice ha spostato <strong>la</strong> sua attenzione sull’architettura del Pentium ® M, molto<br />

più efficiente a parità <strong>di</strong> frequenza <strong>di</strong> funzionamento, cominciando lo sviluppo<br />

<strong>di</strong> alcuni derivati de<strong>di</strong>cati al segmento desktop e piccoli server. Infatti<br />

l’architettura del Pentium ® M, è ottimizzata anche dal punto <strong>di</strong> vista energetico,<br />

ed è basata sul design del Pentium ® III. Questo significa essenzialmente che<br />

<strong>Intel</strong> ® è tornata al Pentium ® III e che del Pentium ® 4 sopravviverà solo il sistema<br />

del FSB, oltre ovviamente ad una serie <strong>di</strong> tecnologie col<strong>la</strong>terali come Hyper-<br />

Threa<strong>di</strong>ng, SSE2, SSE3, EM64T e XD-bit.<br />

Il primo Pentium ® 4 aveva core Wil<strong>la</strong>mette ed operava ad una frequenza <strong>di</strong> 1,5<br />

GHz. Inizialmente <strong>la</strong> sua architettura lo rendeva più lento <strong>dei</strong> propri antagonisti,<br />

Pentium ® III ed Athlon, ma poi l’enorme sca<strong>la</strong>bilità gli consentì <strong>di</strong> arrivare in


Storia <strong>dei</strong> <strong>processori</strong> <strong>Intel</strong>® 271<br />

meno <strong>di</strong> una anno al<strong>la</strong> barriera "storica" <strong>dei</strong> 2 GHz, soglia a cui dovette cedere il<br />

passo al suo successore Northwood.<br />

Per abbattere <strong>la</strong> barriera <strong>dei</strong> 2 GHz, arrivò Northwood, i cui miglioramenti<br />

consistevano in un ampliamento del<strong>la</strong> memoria cache L2, che passava da 256<br />

KB a 512 KB, e il passaggio ad un nuovo processo <strong>di</strong> produzione a 130 nm.<br />

Cambiò anche il socket che <strong>di</strong>venne il 478, e col tempo arrivarono anche<br />

aggiornamenti al<strong>la</strong> frequenza <strong>di</strong> BUS che passò dagli iniziali 400 MHz, a 533<br />

MHz e poi ad<strong>di</strong>rittura a 800 MHz. Dal modello a 3,06 GHz (l’ultimo a 533<br />

MHz <strong>di</strong> bus) venne introdotta anche <strong>la</strong> tecnologia Hyper-Threa<strong>di</strong>ng che venne<br />

estesa a tutta l’ultima gamma con bus a 800 MHz da 2,4 GHz fino all’ultimo<br />

Northwood arrivato sul mercato a 3,4 GHz.<br />

Nel settembre del 2003 fu annunciato all’ <strong>Intel</strong> ® Developer Forum il Pentium ® 4<br />

Extreme E<strong>di</strong>tion (P4EE), poco più <strong>di</strong> una settimana prima del <strong>la</strong>ncio dell’Athlon<br />

64 e dell’Athlon 64 FX (anche se <strong>la</strong> sua commercializzazione, per <strong>la</strong> verità<br />

molto scarsa, iniziò solo il 3 novembre). Il design rimaneva pressoché invariato<br />

rispetto al Northwood (per farlo funzionare sulle stesse schede madri), ma<br />

possedeva ulteriori 2 MB <strong>di</strong> cache L3 ere<strong>di</strong>tati dal progetto dello Xeon Gal<strong>la</strong>tin.<br />

Un anno più tar<strong>di</strong>, il 15 novembre 2004 fu aumentata <strong>la</strong> velocità <strong>di</strong> bus da 800<br />

MHz a 1066 MHz, con un piccolo miglioramento delle prestazioni, ma fu<br />

ri<strong>la</strong>sciato solo un chip che utilizzava tale frequenza <strong>di</strong> bus, il modello a 3,46<br />

GHz. Successivamente anche il Pentium ® 4 Extreme E<strong>di</strong>tion passò al core


272 Appen<strong>di</strong>ce B<br />

Prescott. Il nuovo EE a 3,73 GHz aveva le stesse caratteristiche <strong>di</strong> un Prescott<br />

del<strong>la</strong> serie 6x0, ma con un bus a 1066 MHz.<br />

Il 2 febbraio 2004 <strong>Intel</strong> ® <strong>la</strong>nciò un nuovo core, chiamato Prescott. Questo era<br />

prodotto con un processo a 90 nm, mai usato prima, ed era una revisione<br />

profonda del processore, tanto che alcuni si stupirono del fatto che non fu<br />

chiamato "Pentium ® 5". Le sue caratteristiche dovevano consentirgli <strong>di</strong><br />

ricominciare <strong>la</strong> "corsa ai GHz", ma non fu propriamente così; essa<br />

effettivamente ripartì ma si arresto velocemente a 3,8 GHz senza nemmeno<br />

raggiungere <strong>la</strong> soglia "psicologica" <strong>dei</strong> 4 GHz originariamente previsti.<br />

Considerando che <strong>Intel</strong> ® prevedeva <strong>di</strong> poter portare il Pentium ® 4 fino a 10 GHz,<br />

questo resta l’insuccesso più pubblicizzato, se non più grave, nel<strong>la</strong> storia del<br />

marchio. <strong>Intel</strong> ® ha ri<strong>la</strong>sciato il 21 febbraio 2005 un nuovo processore Prescott,<br />

chiamato "6xx", con tecnologie EM64T, XD-bit e SpeedStep oltre ad una cache<br />

L2 <strong>di</strong> 2 MB. Il vantaggio <strong>di</strong> quest’ultima è tuttavia pressoché annichilito<br />

dall’alta <strong>la</strong>tenza <strong>di</strong> questa e dal<strong>la</strong> doppia <strong>di</strong>mensione delle parole in modalità<br />

EM64T: risulta quin<strong>di</strong> un tentativo <strong>di</strong> mantenere le performance anche in<br />

modalità 64 bit.<br />

Ad inizio 2006 è stato ri<strong>la</strong>sciato il nuovo core Cedar Mill, un Prescott costruito<br />

con processo produttivo a 65 nm. L’architettura è <strong>la</strong> stessa <strong>di</strong> Prescott, e anche<br />

le tecnologie implementate sono le stesse presenti nelle ultime evoluzoni del<br />

predecessore. Monta una pipeline a 31 livelli (come Prescott) e, sempre come


Storia <strong>dei</strong> <strong>processori</strong> <strong>Intel</strong>® 273<br />

Prescott, ha 2MiB <strong>di</strong> cache L2. La gamma <strong>di</strong> frequenze va da 2.8 GHz a 3.8<br />

GHz. Cedar Mill risolve i problemi <strong>di</strong> temperatura del predecessore con una<br />

tolleranza fino a 86 W e implementa le nuove tecnologie <strong>di</strong> virtualizzazione<br />

Vanderpool.<br />

2005: PROCESSORE PENTIUM ® D<br />

Il Pentium ® D è il primo processore dual core prodotto da<br />

<strong>Intel</strong> ® ed è de<strong>di</strong>cato al settore Desktop. Nel<strong>la</strong> sua prima<br />

versione era basato sul core Smithfield, che è stato poi<br />

sostituito dal<strong>la</strong> propria evoluzione, Presler.<br />

Il Pentium ® D inoltre, è il primo processore che supporta il<br />

DCTP-IP, tecnologia necessaria al Digital rights management.<br />

La sua caratteristica principale, innovativa e, senza ombra <strong>di</strong> dubbio,<br />

rivoluzionaria, risiede nel fatto che esso è, come accennato prima, il primo<br />

processore dual core commercializzato dal<strong>la</strong> <strong>Intel</strong> ® . Il suo <strong>la</strong>ncio è stato seguito<br />

dopo pochi giorni da quello dell’Athlon 64 X2 prodotto da AMD ® . In realtà il<br />

Pentium ® D non è il primo microprocessore dual core arrivato sul mercato: già<br />

IBM con i suoi PowerPC aveva raggiunto questo traguardo un paio <strong>di</strong> anni<br />

prima, e altri produttori avevano seguito <strong>la</strong> sua strada, ma l’avvento del<br />

Pentium ® D segna comunque un’epoca in quanto praticamente solo <strong>Intel</strong> ® e<br />

AMD ® si contendono <strong>la</strong> grossa fetta del mercato <strong>di</strong> massa <strong>dei</strong> micro<strong>processori</strong>.<br />

Ma perché si è passati alle architetture a doppio core? Per un motivo molto<br />

semplice: ormai da più <strong>di</strong> due anni le frequenze <strong>dei</strong> <strong>processori</strong> erano


274 Appen<strong>di</strong>ce B<br />

praticamente ferme. Dopo anni in cui queste ultime sono cresciute<br />

vertiginosamente, con le presentazioni <strong>di</strong> nuovi modelli ogni circa 2 mesi con<br />

200 MHz <strong>di</strong> salto, si è arrivati velocemente ai 3 GHz e sono nati i problemi. Il<br />

passaggio ai 90 nm non ha dato i risultati sperati, e l’avvento del core Prescott<br />

per i Pentium ® 4 è stato molto travagliato e non privo <strong>di</strong> <strong>di</strong>fficoltà e delusioni.<br />

AMD ® aveva abbandonato <strong>la</strong> "corsa ai MHz" già da <strong>di</strong>verso tempo e <strong>Intel</strong> ® si è<br />

trovata costretta a fare altrettanto, migliorando l’efficienza dell’architettura e<br />

sviluppando il calcolo parallelo. In fondo è una logica conseguenza: se non si<br />

riesce ad aumentare <strong>la</strong> velocità con cui si esegue un’operazione, per aumentare<br />

le prestazioni bisogna aumentare il numero <strong>di</strong> operazioni che si possono<br />

compiere nell’unità <strong>di</strong> tempo, e il continuo affinamento <strong>dei</strong> processi costruttivi e<br />

<strong>la</strong> miniaturizzazione hanno consentito <strong>di</strong> imboccare questa nuova via.<br />

Nel 2007 sono arrivate le architetture a 4 core e poi via via nel tempo si passerà<br />

a quelle multi core.<br />

Il primo Pentium ® D arrivato sul mercato è basato sul Smithfield, che<br />

fondamentalmente è formato da due core Pentium ® 4 Prescott integrati nello<br />

stesso package. Ha una cache L2 <strong>di</strong> 2 MB equamente sud<strong>di</strong>visa tra i 2 core, e<br />

con<strong>di</strong>vide con l’ultima evoluzione <strong>di</strong> Prescott tutte le tecnologie accessorie, tra<br />

cui il processo costruttivo a 90 nm e le istruzioni SSE, SSE2, SSE3, EM64T,<br />

SpeedStep. Nel<strong>la</strong> versione Pentium ® Extreme E<strong>di</strong>tion viene integrato anche il<br />

supporto Hyper-Threa<strong>di</strong>ng.<br />

Il successore <strong>di</strong> Smithfield è Presler, arrivato sul mercato nel gennaio 2006. È<br />

costruito a 65 nm ed è il primo processore <strong>Intel</strong> ® dual core con i due core


Storia <strong>dei</strong> <strong>processori</strong> <strong>Intel</strong>® 275<br />

<strong>di</strong>stinti sul package. Le frequenze sono <strong>legge</strong>rmente più alte <strong>di</strong> Smithfield, dai<br />

2,8 GHz ai 3,4 GHz inizialmente, ma successivamente è stata presentata una<br />

versione a 3,6 GHz. Si tratta inoltre dell’ultimo processore <strong>Intel</strong> ® basato<br />

sull’architettura NetBurst del Pentium ® 4.<br />

2006: PROCESSORE CORE 2 DUO<br />

Core 2 Duo è il nome commerciale <strong>di</strong> una serie <strong>di</strong><br />

micro<strong>processori</strong> x86 <strong>di</strong> ottava generazione sviluppati da<br />

<strong>Intel</strong> ® , presentati il 27 luglio 2006.<br />

A <strong>di</strong>fferenza <strong>di</strong> quanto accaduto in passato, <strong>Intel</strong> ® ha<br />

deciso <strong>di</strong> raggruppare sotto il nome <strong>di</strong> Core 2 Duo<br />

<strong>di</strong>versi <strong>processori</strong> (i primi esponenti sono Merom e<br />

Conroe) destinati a <strong>di</strong>versi settori <strong>di</strong> mercato. Per <strong>la</strong> prima volta infatti sia il<br />

mercato <strong>dei</strong> sistemi portatili che <strong>dei</strong> sistemi desktop si basano su un unico<br />

processore.<br />

Nel<strong>la</strong> versione desktop Core 2 Duo è il successore del Pentium ® D Presler,<br />

mentre nell’ambito mobile è il successore del Core Duo Yonah.<br />

La nuova architettura, comune anche al fratello maggiore Core 2 Extreme,<br />

deriva in parte da quel<strong>la</strong> del Pentium ® M e più specificatamente da quel<strong>la</strong> del<br />

suo primo successore dual core, il Core Duo Yonah. <strong>Intel</strong> ® comunque ha<br />

<strong>di</strong>chiarato che le innovazioni apportate con Core 2 Duo sono <strong>di</strong>verse <strong>di</strong><br />

conseguenza l’azienda vuole propor<strong>la</strong> come un’architettura completamente<br />

nuova denominata <strong>Intel</strong> ® Core Microarchitecture (o P8), e viene identificata<br />

come successore del<strong>la</strong> precedente architettura NetBurst (o P7).


276 Appen<strong>di</strong>ce B<br />

L’introduzione del Core 2 Duo, inoltre, ha segnato nel<strong>la</strong> gamma <strong>Intel</strong> ®<br />

l’abbandono del nome storico "Pentium" per <strong>la</strong> fascia alta del mercato, per <strong>la</strong><br />

prima volta dal 1993, relegandolo al<strong>la</strong> fascia me<strong>di</strong>o/bassa.<br />

L’introduzione del Core 2 Duo ha segnato un punto <strong>di</strong> svolta nel<strong>la</strong> politica <strong>di</strong><br />

mercato <strong>di</strong> <strong>Intel</strong> ® . La sua adozione in ambito desktop, infatti è coincisa con <strong>la</strong><br />

morte dell’architettura NetBurst che è al<strong>la</strong> base del Pentium ® 4 e <strong>dei</strong> Pentium ® D<br />

(Smithfield e Presler) e che si è rive<strong>la</strong>ta efficace in un momento in cui<br />

aumentare <strong>la</strong> frequenza <strong>di</strong> clock non era un problema, ma straor<strong>di</strong>nariamente<br />

inefficiente dal punto <strong>di</strong> vista del rapporto prestazioni/Watt. Prendendo come<br />

riferimento l’architettura NetBurst del Pentium ® 4 Northwood, <strong>Intel</strong> ® è arrivata<br />

con Conroe a quintuplicare l’efficienza, e quin<strong>di</strong> le prestazioni, a parità <strong>di</strong> Watt<br />

<strong>di</strong>ssipati. È evidente inoltre, come fino a Smithfield che mantiene<br />

fondamentalmente <strong>la</strong> stessa architettura del Pentium ® 4, tale aumento sia stato<br />

molto marginale. Dato che ormai aumentare il clock è <strong>di</strong>ventato quasi<br />

impossibile senza l’insorgere <strong>di</strong> numerose complicazioni legate al<strong>la</strong><br />

<strong>di</strong>ssipazione termica, quel<strong>la</strong> dell’efficienza dell’architettura e <strong>la</strong><br />

parallelizzazione delle operazioni, sembra <strong>la</strong> strada migliore per proseguire il<br />

processo <strong>di</strong> innovazione.<br />

2007 CORE 2 QUAD<br />

Core 2 Quad è il nome commerciale <strong>di</strong> un processore che<br />

<strong>Intel</strong> ® ha presentato l’8 gennaio 2007 come variante<br />

"economica" <strong>dei</strong> primi <strong>processori</strong> a 4 core Core 2 Extreme,<br />

basati sull’architettura <strong>Intel</strong> ® Core Microarchitecture. Lo scopo <strong>di</strong> questo


Storia <strong>dei</strong> <strong>processori</strong> <strong>Intel</strong>® 277<br />

prodotto era quello <strong>di</strong> <strong>di</strong>ventare <strong>la</strong> "porta d’ingresso" ai <strong>processori</strong> a 4 core<br />

in<strong>di</strong>rizzati a tutto il mercato e non solo agli appassionati che storicamente sono<br />

gli unici ad essere attratti dal<strong>la</strong> versione Extreme. Proprio per questo motivo si<br />

inseriva nel<strong>la</strong> fascia <strong>di</strong> mercato tra i Core 2 Duo, che sono <strong>processori</strong> dual core<br />

e i Core 2 Extreme da 4 core e con clock ancora più elevati.<br />

Essendo <strong>la</strong> prima CPU a 4 core prodotta da <strong>Intel</strong> ® (e basata sul core Kentsfield),<br />

insieme ai Core 2 Extreme, non esiste un vero e proprio predecessore del Core 2<br />

Quad; è possibile in<strong>di</strong>carne uno possibile nel Pentium ® D Presler che era<br />

anch’esso un processore dual core, sebbene basato sul<strong>la</strong> vecchia architettura<br />

NetBurst (derivata dal Pentium ® 4). Più precisamente si può in<strong>di</strong>care il<br />

Pentium ® D come il predecessore comune sia al Core 2 Quad che al Core 2 Duo.<br />

Tra <strong>la</strong> fine del 2007 e l’inizio del 2008, con il passaggio al nuovo processo<br />

produttivo a 45 nm, venne ri<strong>la</strong>sciata <strong>la</strong> nuova generazione del Core 2 Quad,<br />

basata sul nuovo core Yorkfield e, successivamente, ad agosto 2008, anche una<br />

versione mobile basata sul core Penryn; si trattava del primo processore mobile<br />

a 4 core realizzato da <strong>Intel</strong> ® .<br />

2008: PROCESSORE CORE I7<br />

Core i7 è il nome commerciale <strong>di</strong> una serie <strong>di</strong><br />

micro<strong>processori</strong> x86 <strong>di</strong> nona generazione sviluppati da<br />

<strong>Intel</strong> ® e presentati il 17 novembre 2008.<br />

Le CPU Core i7, insieme alle controparti <strong>di</strong> fascia più alta Core i7 Extreme,<br />

sono le prime incarnazioni del<strong>la</strong> nuova architettura Nehalem, successiva al<strong>la</strong><br />

<strong>Intel</strong> ® Core Microarchitecture, e che andrà progressivamente a sostituire in tutti


278 Appen<strong>di</strong>ce B<br />

i settori <strong>di</strong> mercato, prendendo gradualmente il posto <strong>dei</strong> Core 2 Duo, Core 2<br />

Quad e Core 2 Extreme.<br />

Sembra che <strong>Intel</strong> ® abbia intenzione <strong>di</strong> in<strong>di</strong>care con il nome <strong>di</strong> Core i7 solo i<br />

<strong>processori</strong> destinati al<strong>la</strong> fascia più alta del mercato desktop, mentre per <strong>la</strong> fasce<br />

<strong>di</strong> mercato inferiori e il settore mobile, probabilmente verranno utilizzati altri<br />

nomi commerciali, tra questi il più probabile è Core i5, atteso nel terzo trimestre<br />

2009 per <strong>la</strong> fascia me<strong>di</strong>a del mercato desktop.<br />

La nuova architettura, comune anche al fratello maggiore Core i7 Extreme,<br />

deriva in parte dal<strong>la</strong> "Core" <strong>dei</strong> predecessori, ma <strong>Intel</strong> ® ha comunque <strong>di</strong>chiarato<br />

che le innovazioni apportate sono talmente tante che è assolutamente doveroso<br />

considerare il nuovo progetto come un vero e proprio salto generazionale e non<br />

solo come un affinamento.<br />

<strong>Intel</strong> ® inoltre ha reso noto che <strong>la</strong> scelta del nuovo nome commerciale Core i7<br />

non ha una motivazione ben precisa, ma esprime comunque chiaramente<br />

l’intenzione <strong>di</strong> mantenere una certa continuità con <strong>la</strong> precedente serie Core 2<br />

grazie all’uso del suffisso "Core".<br />

La produzione <strong>dei</strong> <strong>processori</strong> Core i7 avviene nei 3 stabilimenti che <strong>Intel</strong> ® ha<br />

negli Stati Uniti, e in partico<strong>la</strong>re in quello <strong>di</strong> Hillsboro in Oregon (dove tra<br />

l’altro ha sede proprio il centro <strong>di</strong> sviluppo che ha progettato <strong>la</strong> nuova<br />

architettura) e in quelli situati in Arizona e New Mexico.


Bibliografia<br />

1. Wechsler, Ofri. Inside <strong>Intel</strong>® Core Microarchitecture: Setting New<br />

Standards for Energy-Efficient Performance. 2006.<br />

2. <strong>Intel</strong>® Corporation. ENERGY-EFFICIENT PERFORMANCE ON THE CLIENT: A<br />

Proposed Measurement Methodology. 2007.<br />

3. Saracco, Roberto. Il futuro del<strong>la</strong> Legge <strong>di</strong> <strong>Moore</strong>. s.l. : Apogeo, 2002.<br />

4. Patterson, Hennessy and. Computer Architecture: A Quantitative Approach,<br />

4th e<strong>di</strong>tion. 2006.<br />

5. <strong>Moore</strong>, Gordon E. Cramming more components onto integrated circuits.<br />

Electronics. 1965, Vol. 38, 8.<br />

6. <strong>Intel</strong>® Corporation. <strong>Moore</strong>'s Law. Sito Web <strong>Intel</strong> Corporation. [Online] 2009.<br />

http://www.intel.com/technology/moores<strong>la</strong>w/index.htm?iid=tech_silicon_mo<br />

ores<strong>la</strong>w+rhc_moore_<strong>la</strong>w.<br />

7. <strong>Moore</strong>, Gordon E. Progress in <strong>di</strong>gital integrated electronics. Procee<strong>di</strong>ngs of<br />

International Electron Devices Meeting. 1975, Vol. 21, p. 11-13.<br />

8. Bucci, Giacomo. Architettura e organizzazione <strong>dei</strong> calco<strong>la</strong>tori elettronici. s.l. :<br />

McGraw-Hill, 2009.<br />

9. Amdhal, Gene M. The logical design of an inetrme<strong>di</strong>ate speed <strong>di</strong>gital<br />

computer. 1951. PhD.Thesis.<br />

10. Microprogramming and the Design of the control Circuits in an Electronic<br />

Digital Computer. Wilkes, M.V. e Stinger, J.B. 1953, Procee<strong>di</strong>ngs of the<br />

Cambridge Philosophical Society, p. 230-238.<br />

11. Very high-speed computing systems. Flynn, Michael J. 12, Dec 1966,<br />

Procee<strong>di</strong>ngs of the IEEE, Vol. 54, p. 1901 - 1909.<br />

12. Pomerene, James H. Machine for multiple instruction execution. 4.295.193<br />

[a cura <strong>di</strong>] International Business Machines Corporation. USA, 1981.<br />

13. Evaluating Associativity in CPU Caches. Hill, M.D. e Smith, A.J. 12, 1989,<br />

IEEE Transactions On Computers, Vol. 38, p. 1612-1630.


280 Bibliografia<br />

14. Trace Cache: a Low Latency Approach to High Bandwidth Instruction<br />

Fetching. Rotenberg, Eric, Bennett, Steve e Smith, James E. 1996. Procee<strong>di</strong>ngs<br />

of the 29th Annual International Symposium on Microarchitecture.<br />

15. Marchetti, Lorenzo. Le tecnologie <strong>dei</strong> <strong>processori</strong>: CISC vs RISC. [Online]<br />

http://www.lithium.it/articolo.asp?code=20.<br />

16. <strong>Intel</strong>. <strong>Intel</strong>'s Tick-Tock Model. Sito Web <strong>Intel</strong> Corporation. [Online]<br />

http://www.intel.com/technology/tick-tock/.<br />

17. B. Wopperer, G. Wurthmann. Il processore Pentium - LA nuova<br />

generazione dell'architettura <strong>Intel</strong>. 1993.<br />

18. <strong>Intel</strong> 80486 ("486") Case Study. [Online]<br />

http://www.cs.clemson.edu/~mark/330/colwell/case_486.html.<br />

19. <strong>Intel</strong> Corporation. Intec Architecture Optimization Manual. 1997. Order<br />

Number: 242816-003.<br />

20. Kagan, Michael, et al. MMX Microarchitecture of Pentium® Processors<br />

With MMX Technology and Pentium® II Microprocessors. <strong>Intel</strong> Technology<br />

Journal. Q3, 1997.<br />

21. <strong>Intel</strong> Corporation. <strong>Intel</strong> Architecture Optimization Reference Manual. 1999.<br />

Order Number: 245127-001.<br />

22. <strong>Intel</strong> Corporation. IA-32 <strong>Intel</strong>® Architecture Optimization Reference<br />

Manual. 2005. Order Number: 248966-012.<br />

23. Hinton, Glenn, et al. The Microarchitecture of the Pentium® 4 Processor.<br />

<strong>Intel</strong> Technology Journal. Q1, 2001.<br />

24. <strong>Intel</strong> Corporation. <strong>Intel</strong>® 64 and IA-32 Architectures Optimization Reference<br />

Manual. 2008. Order Number: 248966-017.<br />

25. Koufaty, David e Dobora, T. Marr. Hyperthrea<strong>di</strong>ng Technology in the<br />

netburst Microarchitecture. IEEE Computer Socciety. 2003.<br />

26. K<strong>la</strong>user A., Austin T., Grunwald D., Calder, B. Dynamic hammock<br />

pre<strong>di</strong>cation for non-pre<strong>di</strong>cated instruction set architectures. Parallel<br />

Architectures and Compi<strong>la</strong>tion Techniques,. 1998.


Bibliografia 281<br />

27. Ramanathan, R.M. Exten<strong>di</strong>ng the World’s Most Popu<strong>la</strong>r Processor<br />

Architecture. s.l. : <strong>Intel</strong> Corporation, 2006.<br />

28. Benini, Luca. Ottimizzazioni micro<strong>architetturali</strong> per high performance<br />

computing. 2004.<br />

29. Benini, Luca. Calcolo ad alte prestazioni su architettura ibrida CPU-GPU.<br />

Tesi <strong>di</strong> Laurea. 2006.<br />

30. <strong>Intel</strong> Corporation. White Paper: Exten<strong>di</strong>ng the World’s Most Popu<strong>la</strong>r<br />

Processor Architecture. New innovations that improve the performance and<br />

energy efficiency of <strong>Intel</strong>® architecture. [Elettronico]. 2007.<br />

31. Amdahl’s Law in the Multicore. Hill, M. and Marty, M.R. 7, 2008, IEEE<br />

Computer, Vol. 41, pp. 33-38.<br />

32. Chip Multiprocessing and the Cell. Gschwind, M. 2006, Computing<br />

Frontiers.<br />

33. Sun UltraSPARC T2 Processor. [Online]<br />

http://www.sun.com/processors/UltraSPARC-T2/.<br />

34. <strong>Intel</strong> Announces Dunnington Processor,. [Online]<br />

http://www.intel.com/pressroom/archive/releases/20080317fact.htm.<br />

35. nVIDIA Quadro FX 3700M. [Online]<br />

http://www.nvi<strong>di</strong>a.com/object/product_quadro_fx_3700_m_us.html.<br />

36. GRAPE-DR: 2-Pflops Massively-Parallel Computer with 512-Core, 512-Gflops<br />

Processor Chips for Scientific Computing. Makino, J., Hiraki, K. e M. Inaba.<br />

2007. Proc. of ACM/IEEE Supercomputing’07.<br />

37. Sun, Xian-He e Chen, Yong. Reevaluating Amdahl’s Law in the Multicore<br />

Era. Department of Computer Science, Illinois Institute of Technology. 2008.<br />

http://www.cs.iit.edu.<br />

38. Asanovic, Krste, et al. The Landscape of Parallel Computing Research: A<br />

View from Berkeley. Electrical Engineering and Computer Sciences, University<br />

of California at Berkeley. 2006.<br />

http://www.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-183.html.


282 Bibliografia<br />

39. Designing Reliable Systems from Unrealiable Components: The Challenges<br />

of Transistor Variability and Degradation. Borkar, S. 2005, IEEE Micro, p. 10-16.<br />

40. The Soft Error Problem: An Architectural Perspective,. Mukherjee, S.S.,<br />

Emer, J. e Reinhardt, S.K. 2005. Procee<strong>di</strong>ngs of the 11th International<br />

Symposium on High-Performance Computer Architecture (HPCA-11 2005). p.<br />

243-247.<br />

41. Latency Lags Bandwidth. Patterson, D. 10, Oct 2004, Communications of<br />

the ACM, Vol. 47, p. 71-75.<br />

42. <strong>Intel</strong> Makes a Big Jump in Computer Math. <strong>Moore</strong>, Samuel K. 2008, IEEE<br />

Spectrum, p. 14-15.<br />

43. Hitting the Memory Wall: Implications of the Obvious. Wulf, W.A. e McKee,<br />

S.A. 1, Mar 1995, Computer Architecture News, Vol. 23, p. 20-24.<br />

44. Hennessy, J. e Patterson, D. Computer Architecture: A Quantitative<br />

Approach. 4th e<strong>di</strong>tion. s.l. : Morgan Kauffman, San Francisco, 2007.<br />

45. Standard Performance Evaluation Corporation (SPEC). [Online]<br />

http://www.spec.org/index.html.<br />

46. Eatherton, W. The Push of Network Processing to the Top of the Pyramid.<br />

Slides avai<strong>la</strong>ble at:<br />

http://www.cesr.ncsu.edu/ancs/slides/eathertonKeynote.pdf keynote address<br />

at Symposium on Architectures for Networking and Communications System.<br />

26-28 Oct 2005.<br />

47. Colel<strong>la</strong>, P. Defining Software Requirements for Scientific Computing.<br />

presentation. 2004.<br />

48. Dubey, P. Recognition, Mining and Synthesis Moves Computers to the Era<br />

of Tera. Technology@<strong>Intel</strong> Magazine. Feb 2005.<br />

49. Chen, Y.K. Private Communication. 2006.<br />

50. Comparing Network Processor Programming Environments: A Case Study.<br />

Shah, N., Plishker, W. e Keutzer, K. 2004. Procee<strong>di</strong>ngs of Workshop on<br />

Productivity and Performance in High-End Computing (P-PHEC).


Bibliografia 283<br />

51. DARPA High Productivity Computer Systems home page. [Online] 2006.<br />

http://www.highproductivity.org/.<br />

52. Arvind, et al. RAMP: Research Accelerator for Multiple Processors - A<br />

Community. U.C. Berkeley. 2005. UCB/CSD-05-1412.<br />

53. Ve<strong>la</strong>r<strong>di</strong>, Daniele Oronzo. Tesi <strong>di</strong> Laurea. Analisi comparativa tra <strong>processori</strong><br />

<strong>Intel</strong> ad architettura IA-32 e IA-64. 2004.<br />

54. Architettura <strong>dei</strong> calco<strong>la</strong>tori - Un approccio strutturale. Tanenbaum, A.S.<br />

s.l. : Pearson Education Italia, 2006.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!