Aspetti energetici in piattaforme di calcolo eterogeneo

Scuol
aPol
i
t
ecni
caedel
l
eSci
enz
edi
Base
Cor
sodi
Laur
eai
nI
ngegner
i
aI
nf
or
mat
i
ca
El
abor
at
ofinal
ei
n PROGRAMMAZI
ONEI
Aspet
t
iener
get
i
cii
npi
at
t
af
or
medical
col
o
et
er
ogeneo
AnnoAccademi
c
o2014/
2015
Candi
dat
o:
Andr
eaScognami
gl
i
o
mat
r
.N46001416
... Ero così sicuro che al traguardo fossimo io e te
ma il quadro è sempre perfetto se lo guardi da cento e un metri ... Ho sempre creduto che avrei condiviso con te la soddisfazione e la gioia di
questo giorno.
Non preoccuparti, però... una parte di te c'era e ci sarà sempre,
indelebile nella mia mente.
Ad Antonio...
1
Indice
1 Introduzione
3
1.1
Obiettivi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
1.2
Processi Tecnologici . . . . . . . . . . . . . . . . . . . . . . . .
3
1.3
Performance e Consumi
4
1.4
High Performance Computing
1.5
Architetture Eterogenee
1.6
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
5
. . . . . . . . . . . . . . . . . . . . .
5
Overhead nei Processori Programmabili . . . . . . . . . . . . .
6
2 GPP
8
2.1
Storia
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8
2.2
Architettura . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
2.3
CPU Multicore
. . . . . . . . . . . . . . . . . . . . . . . . . .
3 GPU
11
12
3.1
Storia
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
3.2
Architettura e Parallelismo . . . . . . . . . . . . . . . . . . . .
14
3.3
Modelli di Programmazione
18
. . . . . . . . . . . . . . . . . . .
4 FPGA
25
4.1
Storia
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
4.2
Origini - PLA e CPLD . . . . . . . . . . . . . . . . . . . . . .
25
4.3
Architettura . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
5 Ecienza Energetica
30
5.1
Energy Ecient System Design
. . . . . . . . . . . . . . . . .
30
5.2
Consumo Energetico
. . . . . . . . . . . . . . . . . . . . . . .
31
6 Energy Awareness nei Compilatori
33
6.1
Riduzione attività di Switching
. . . . . . . . . . . . . . . . .
6.2
Allocazione Risorse . . . . . . . . . . . . . . . . . . . . . . . .
33
6.3
Power-Management a Run-Time . . . . . . . . . . . . . . . . .
34
6.4
Ottimizzazione dell'Instruction Set Architecture (ISA)
35
. . . .
7 Conclusioni
7.1
Confronto tra architetture
33
36
. . . . . . . . . . . . . . . . . . . .
8 Bibliograa
36
38
2
1 Introduzione
1.1 Obiettivi
Il lavoro arontato da questo elaborato si propone di studiare varie
piattaforme di calcolo, comprendendone la storia, la struttura e l'evoluzione.
Successivamente vengono esposte le tecniche che ne permettono
l'interazione, sotto forma di architetture eterogenee (spesso realizzate con
tecnologia
System-on-Chip).
Dopo un'iniziale studio dell'evoluzione dei diversi processi tecnologici, del
ruolo del consumo energetico e dei vantaggi ottenibili dall'uso combinato di
dierenti sorgenti di calcolo, in piattaforme eterogenee, vengono arontate
nel dettaglio tre diverse piattaforme:
GPP, GPU e FPGA.
In seguito, l'elaborato tratta l'impatto energetico sulle suddette tecnologie e
delle possibili tecniche realizzabili per il miglioramento dei consumi, quali:
riduzione attività di switching, allocazione risorse e
power-management in fase di compilazione.
Inne, anticipando le dovute conclusioni, vengono arontati i processi di
Energy
progettazione e sviluppo in ottica di risparmio energetico, come l'
Eciency Systems Design e l'Energy Awareness nei compilatori.
1.2 Processi Tecnologici
Nel 1965, Gordon Moore, co-fondatore della Intel, quanticò la
straordinaria crescita della tecnologia dei semiconduttori in una altrettanto
straordinaria analisi.
Infatti, in seguito ad un approfondito studio durato circa 10 anni, Moore
osservò che la densità dei Transistor all'interno dei chip raddoppiava ad
intervalli regolari, e che questa crescita sarebbe continuata per lungo tempo.
Quest'osservazione, nota come
Legge di Moore, si è dimostrata valida per
un periodo oltre i 40 anni e si basava sulla continua evoluzione nel campo
dei semiconduttori, dei transistor e dei circuiti integrati.
L'invenzione del
Circuito Integrato, risalente al 1958, permise la
realizzazione di un chip composto da diversi transistor.
Una proprietà che n da subito colpì l'intero mondo dell'elettronica, perché
permise la realizzazione di chip con un sempre crescente numero di
transistor pur tenendo praticamente invariato il costo di fabbricazione.
Per avere un'idea dell'evoluzione del numero di transistor nei
microprocessori negli anni, in Figura 1 riportiamo alcuni prodotti della
Intel.
Negli ultimi anni, le performance dei processori sono andate stabilizzandosi
e sono emersi nuovi fattori che hanno iniziato a mettere in discussione una
legge che sembrava essere immutabile.
Ad esempio, la
Frequenza di Clock nei processori, è rimasta invariata nel
corso degli ultimi 5 anni.
In realtà, Intel nel 2001 stimò che la frequenza dei processori sarebbe
arrivata intorno ai 30GHz, ma nel 2005 l'azienda stessa cambiò radicalmente
direzione, bloccando l'evoluzione della frequenza di clock ed adandosi a
dierenti tecnologie per evolvere e migliorare i propri processori.
La causa principale che ha portato le varie aziende (Intel, AMD) ad
interrompere il trend di crescita riguardante la frequenza di clock ha a che
fare con il Consumo Energetico dei calcolatori e con la Dissipazione di
Calore.
3
Inoltre, con l'introduzione di
CPU Multicore è risultato inutile aumentare
a dismisura la potenza dei microprocessori quando risultava più semplice
raggiungere lo stesso livello di performance aumentandone il numero.
Nei Multicore, ogni Core dispone della propria pipeline di esecuzione ed è in
grado di portare avanti in maniera autonoma l'esecuzione di un thread.
Inoltre, questo tipo di processori sposano perfettamente la losoa
Multitasking dei comuni sistemi operativi, nei quali la parallelizzazione delle
operazioni trova maggior vantaggio rispetto alla loro esecuzione sequenziale.
Figura 1: Numero di transistor nei processori Intel
1.3 Performance e Consumi
Al crescere delle Performance, anche i Consumi incominciano ad essere
rilevanti, se non per dispositivi
per quelli
Fissi, quali Desktop PC
Mobili, come Smartphone
o Mainframe, ma
o Portatili.
Inoltre il mercato richiede sempre più una stretta collaborazione tra quello
che è il mondo dell'informatica e della tecnologia e quello di moda e arte.
Uno Smartphone al giorno d'oggi, non deve essere solo funzionale e
performante, ma deve essere anche leggero e fashionable .
Per soddisfare i sempre più stringenti requisiti dei dispositivi mobili, la
crescita della capacità delle batterie è stata fortemente limitata, come si
evince dalle speciche degli Iphone degli ultimi 10 anni, in Figura 2.
Questo trend ha obbligato i progettisti dei sistemi embedded a sviluppare
sistemi HPC (High Perfomance Computer) con una sempre più bassa quota
di energia a disposizione, rendendo l'
Energy Eciency un aspetto
fondamentale del processo di progettazione di sistemi embedded.
4
Figura 2: Speciche di Iphone di diverse generazioni
1.4 High Performance Computing
In informatica con il termine
High Performance Computing (HPC) ci
si riferisce alle tecnologie utilizzate da computer cluster per creare dei
sistemi di elaborazione in grado di fornire delle prestazioni molto elevate
nell'ordine dei PetaFLOPS, ricorrendo tipicamente al calcolo parallelo.
Il termine è molto utilizzato essenzialmente per sistemi di elaborazioni
utilizzati in campo scientico.
Il modello di calcolo ad alte prestazioni, HPC, è nato a partire dagli anni
'90, e si basava sui processori tradizionali, cioè su CPU, che garantivano un
continuo miglioramento grazie all'adabilità della legge di Moore.
Tuttavia, quando la legge di Moore ha incominciato a mostrare i propri
limiti, nell'ultimo decennio circa, ci si è diretti verso soluzioni Multicore e
architetture Eterogenee.
1.5 Architetture Eterogenee
Architettura Eterogenea più dispositivi HW, spesso saldati su
uno o più SoC (system-on-a-chip), interagiscono e collaborano al ne di
In una
eseguire il maggior numero di task nel più breve tempo possibile.
Nelle architetture Eterogenee tipicamente viene aancato al tradizionale
processore multicore, un coprocessore (o acceleratore) in grado di fornire
elevate prestazioni a consumi contenuti.
Questo tipo di soluzioni sono più performanti rispetto ai classici modelli a
Singolo Processore, però richiedono un maggior impegno nella fase di
progettazione e soprattutto di programmazione.
Infatti, basti pensare che non è possibile adottare un unico standard di
programmazione ad alto livello (C o C++), che discerne dalla particolare
architettura, poiché spesso i programmatori HPC sono riluttanti a
sacricare le prestazioni in cambio di una maggiore facilità di
programmazione.
Un'altra problematica legata alle architetture eterogenee è dovuta
all'abitudine dei programmatori a ragionare in modo sequenziale.
Infatti, anche se parte della conversione da software applicativo sequenziale
a parallelo può essere eseguita in maniera automatica, ai programmatori
resta il compito di parallelizzare manualmente quegli algoritmi che sono
stati pensati in modo essenzialmente seriale.
5
1.6 Overhead nei Processori Programmabili
La Figura 3 mostra il trade-o che c'è tra essibilità ed ecienza nella
progettazione di sistemi di calcolo.
Figura 3: Trade-o tra l'ecienza e la essibilità
Infatti, in funzione di quale dei due aspetti vogliamo maggiormente
enfatizzare, la scelta del progettista ricade su una dierente famiglia di
architetture.
In generale possiamo classicare ogni architettura in due classi: Special
Purpose e General Purpose.
ASIP e ASIC appartengono alla prima classe e rappresentano degli approcci
altamente specici, volti alla risoluzione di un unico problema.
Consentono di raggiungere delle prestazioni in termini di velocità di
processamento e consumo elettrico dicilmente ottenibili con l'uso di
soluzioni general purpose, quali FPGA, GPU e GPP.
Per raggiungere un alto livello di ecienza quindi, si implementano circuiti
integrati ad-hoc per le varie applicazioni (ASICs -
Integrated Circuits).
Application Specic
In questi circuiti però, l'alto livello di ecienza si contrappone con la quasi
totale mancanza di essibilità.
Infatti, in architettura ASIC, dopo che il circuito è stato progettato e
stampato per una particolare applicazione, non può essere più riadattato
per svolgere compiti diversi da quelli per cui è nato.
Tale mancanza di essibilità è un punto a sfavore per questo tipo di
soluzioni, dal momento che nei moderni dispositivi embedded, uno dei
requisiti fondamentali è la capacità di evolvere velocemente in funzione del
mercato o degli utenti stessi.
L'altra faccia della medaglia è invece composta da piattaforme
perfettamente programmabili, che quindi assicurano la massima essibilità
possibile, a scapito dell'ecienza stessa.
General Purpose Processors, categoria di cui fanno parte anche le
CPU, forniscono la miglior essibilità, permettendo l'esecuzione virtuale di
ogni tipo di applicazione, al costo di avere performance decisamente minori
e costi energetici molto più elevati.
Il gap di ecienza energetica tra architetture General Purpose Processors
(GPPs) e Application Specic Integrated Circuits (ASICs) è enorme.
Infatti le GPPs possono consumare no a qualche ordine di grandezza in
più di un ASIC che svolge lo stesso onere computazionale.
6
Quest'enorme divario energetico, dovuto all'overhead presente
nell'architettura GPP, risiede nella presenza di risorse e istruzioni che hanno
lo scopo di gestire e eseguire operazioni per più e diversi tipi di applicazioni.
ASICs e GPPs sono gli estremi di questo compromesso tra ecienza e
essibilità.
Esistono altri tipi di architetture che orono un compromesso diverso
rispetto ai due precedenti.
Application Specic Instruction-Set Processors (ASIPs) adattano
l'ISA (Instruction Set Architecture) per uno specico set di applicazioni,
allo scopo di incrementare l'ecienza di un processore a livelli paragonabili
ad un'architettura ASIC.
Field Programmable Gate Array (FPGA) ore un'elevata essibilità
attraverso un livello hardware strutturato a blocchi ricongurabili.
Graphics Processing Units (GPUs), progettate inizialmente per il
rendering graco, al giorno d'oggi trovano applicazione anche in altri
domini applicativi, specialmente in quelli scientici.
7
2 GPP
L'unità di elaborazione centrale (CPU -
Central Processing Unit) è una
tipologia di processore digitale general purpose.
Per semplicità il seguente capitolo non convergerà sulle GPP, ma sulle CPU
che sono nient'altro che una loro specializzazione.
2.1 Storia
La storia della Central Processing Unit è concentrata in un tempo
relativamente breve, e nonostante ciò, ha rivoluzionato quasi ogni aspetto
delle nostre vite.
Nei primi anni '70, l'Intel produsse l'
Intel 4004 (Figura 4 ), il primo
microprocessore monolitico (cioè interamente contenuto in un solo circuito
integrato) della storia ad essere commercializzato.
La massima frequenza di clock raggiungibile da questo rivoluzionario
dispositivo era 740KHz, una velocità sorprendente a quei tempi, che
permetteva l'esecuzione di 92.000 istruzioni al secondo, e composto da circa
2.300 Transistor.
Figura 4: Intel 4004, 1971
L'Intel già dominava il mercato delle CPU quando, nel 1993, uno dei più
popolari esemplari di CPU nella storia fu reso disponibile al mercato, il
processore
Intel Pentium.
Figura 6: AMD Am5x86, 1995
Figura 5: Intel Pentium, 19921993
Questo dispositivo leggendario operava ad una frequenza di clock di 60MHz,
per un totale di circa 100 milioni di istruzioni al secondo (60 MIPS).
L'assoluto predominio del mercato e totale solitudine nell'innovazione
tecnologica nel campo dei processori da parte dell'Intel continuò per molti
8
anni, no all'uscita, nel 1995, del
competitor, la
AMD.
AM5x86, processore del suo maggior
A seguire, Intel e AMD hanno segnato la storia dei microprocessori,
producendo dispositivi sempre più veloci e performanti.
La successiva pietra miliare nella storia delle CPU fu il rilascio commerciale
del primo processore da 1GHz.
AMD Athlon, nel 1999, e a
Intel Premium III circa due anni dopo.
Questo obiettivo fu raggiunto prima dall'
seguire dall'
Attualmente è comune avere una CPU la cui frequenza di clock supera di
molto 1GHz, anche in dispositivi mobili quali smartphone e tablet.
In appena 40 anni infatti siamo passati da una tecnologia che lavorava a
740KHz ad una che raggiunge diversi GHz di velocità, si è ottenuto un
incremento del numero di transistor sul singolo chip da 2.300 a piu di un
miliardo di unità.
In oltre, da qualche anno a questa parte, Intel e AMD hanno smesso di
trarre dal singolo processore sempre più prestazioni, e si stanno spingendo
verso la computazione parallela, con l'utilizzo di multicore sullo stesso chip.
2.2 Architettura
Esistono diversi aspetti primari di cui i progettisti devono tener conto nella
creazione di una CPU, e alcuni di questi sono: data paths, control unit,
supporti di memorizzazione, circuiteria del clock e logic gate cell library.
Il data path è un insieme di unità di calcolo, come ad esempio le unità di
elaborazione (ALU), i registri e i moltiplicatori necessari per l'esecuzione
delle istruzioni nella CPU.
La control unit, invece, è specializzata nel gestire l'interazione tra data
paths e la memoria principale.
É la componente delle CPU che ha il compito di coordinare tutte le azioni
necessarie per l'esecuzione di una o più istruzioni e dà la possibilità al
microprocessore di eseguire istruzioni diverse.
Per quanto riguarda i supporti di memorizzazione, al giorno d'oggi, le CPU
dispongo di diversi tipi di moduli di memoria integrati sul chip.
Tra queste le più popolari sono i Registri e le Cache, entrambe memorie ad
alta velocità, di tipo SRAM (Static Random Access Memory).
I registri sono celle di memoria strutturate stesso all'interno della CPU e
contengono dati vitali per il corretto svolgimento delle operazioni eseguite
dalle stesse.
Le cache, tipicamente, sono delle memorie interposte tra la CPU e la
memoria principale.
Possono essere di livello uno (L1) e di livello due (L2), sono di capienza
inferiore rispetto alla memoria principale e il loro utilizzo è più conveniente
in termini di tempo di accesso e/o carico sul sistema.
Quando è necessario l'accesso ad un dato, una sua copia viene prima
cercata nella cache.
Se è presente e valida, viene utilizzata tale copia.
Altrimenti il dato viene recuperato dalla memoria principale, e
memorizzato nella cache, nel caso possa servire successivamente.
Il clock della CPU è un segnale periodico, tipicamente generato da un
oscillatore a cristalli.
É ottenuto trasformando un'onda sinusoidale in una quadra e viene
utilizzato per sincronizzare le componenti interne della CPU.
9
Inne, con
logic gate cell library intendiamo una collezione di porte
logiche utilizzate per implementare la logica computazionale nelle CPU, che
consistono di alcune funzioni di basso livello quali AND, OR, INVERT, Flip
Flop, Latches e Buers.
Per dare un'idea, riportiamo in Figura 7 l'architettura dell'AMD K10,
prodotto nel 2007.
Figura 7: Architettura AMD K10
10
2.3 CPU Multicore
Uno degli aspetti principali sui quali si basa l'evoluzione dei microprocessori
è l'utilizzo di soluzioni
Multi-Core.
Il termine multicore viene utilizzato per indicare una CPU composta da 2 o
più core, ovvero da più nuclei di processori sici montati sullo stesso
package.
Attualmente le soluzioni presenti sul mercato comprendono architetture con
2, 4, 8 e 16 core.
Questi tipi di architetture, rispetto alla single core, consentono di
aumentare la potenza di calcolo di una CPU lasciando invariata la frequenza
di clock di lavoro, a tutto vantaggio del calore dissipato (che diminuisce
rispetto al caso di più processori separati) così come dell'energia assorbita.
I beneci del Multicore derivano dalla possibilità di aumentare le
performance attraverso il processing parallelo, basandosi sul principio che
un problema grande può essere facilmente risolto scomponendolo in più
problemi, minori, risolvibili concorrentemente.
In Figura 8, un esempio di architettura quad-core, l'Intel I7 950.
Figura 8: Intel I7 950, 2009
In passato, l'uso del calcolo parallelo era attribuito ad applicazioni di fascia
alta, per la risoluzione di complessi problemi matematici, o comunque in
campi scientici quali la sica, l'ingegneria o la meteorologia.
Oggi, invece, grazie all'aumento di applicazioni commerciali e
all'abbattimento dei costi per la produzione dei complessi circuiti integrati,
il calcolo parallelo si è diuso anche nei comuni dispositivi elettronici quali
smartphone, tablet e PC.
11
3 GPU
L'unità di elaborazione graca GPU -
Graphics Processing Unit è una
tipologia particolare di coprocessore che si contraddistingue per essere
specializzata nel rendering di immagini grache.
Come è stato dichiarato dal Prof. Jack Dongarra, le GPU si sono evolute
al punto che molte applicazioni del mondo reale possono essere facilmente
implementate su di esse e possono essere eseguite in maniera
signicativamente più veloce rispetto ad un'architettura multicore.
I sistemi di calcolo futuri saranno una soluzione basata sul lavoro
combinato tra Parallel-Core GPUs e Multi-Core CPUs.
3.1 Storia
Le GPU si sono evolute rapidamente negli ultimi 30 anni, dalla loro prima
introduzione al mercato.
Nonostante l'enorme sviluppo che le ha riguardate, le GPU trovano
principale applicazione nel mondo del processing delle immagini.
La comparsa delle prime unità grache risale agli anni '80, quando sia Intel
che IBM introdussero prodotti specializzati nel mercato.
Anche altre compagnie si mossero in tal direzione, come Commodore e
Texas Instrument, che aggiunsero semplici funzionalità grache sui loro chip
ed introdussero delle prime e basiliari schede esterne.
Tali schede erano molto costose e realizzavano funzionalità molto semplici,
quali riempire un'area, disegnare una forma e modicare immagini
elementari.
Figura 9: S3 S386C911, 1991
Gli anni '90 sono stati il vero e proprio punto di partenza per quanto
riguarda il decollo delle GPU.
Nel 1991, S3 Graphics ha introdotto il primo acceleratore 2D su singolo
chip, l'S3 86C911 (Figura 9 ).
La corsa alla graca 2D ha caratterizzato questo decennio, imponendo come
nuovo obiettivo delle aziende leader nel campo il processing in 3-Dimensioni.
Verso la ne degli anni '90, il rendering 3D era possibile, ma solo attraverso
l'assistenza delle CPU (soluzione conosciuta come graca 3D-assistita).
Per supportare la diusione delle schede grache, in questo stesso periodo,
nacquero diverse collezioni di API, quali
OpenGL e DirectX.
Ben presto, tali librerie implementarono anche funzionalità per il supporto
della Trasformazione e Illuminazione (T&L - Transform & Lighting),
caratterizzando un enorme salto in avanti nel GPU processing.
12
Transform è il task che permise la produzione di un immagine 2D a partire
da una scena tridimensionale.
Lighting, invece, consentì l'alterazione dei colori delle varie superci delle
scene, in funzione delle informazioni sull'illuminazione.
Nel 1999, con l'uscita sul mercato della
GeForce 256, fu introdotta la
prima generazione di schede grache GeForce prodotte dalla NVIDIA
Corporation, pensate appositamente per la graca 3D.
Figura 10: NVIDIA GeForce 256, 1999
Dall'uscita delle prime schede ad oggi, sono straordinari i miglioramenti
avuti nel rendering 3D delle GPU, spesso guidati da ATI e NVIDIA, che
tuttora detengono la maggior parte della quota di mercato nel processing
graco e che, di conseguenza, impongono le direzioni in cui evolvere.
Un'altra chiave di volta nell'evoluzione delle GPU fu la nascita del
PCI
Express (Peripheral Component Interconnect Express), ucialmente
abbreviato in PCIe (in Figura 11 ).
Il PCI Express è uno standard di interfaccia d'espansione a bus seriale per
calcolatori che garantì velocità di trasferimento molto superiori e permise
l'utilizzo di schede grache con maggior richiesta energetica.
Tali beneci portarono alla costruzione di chip graci molto più evoluti dei
precedenti ed aprirono la strada ad una sempre più realistica graca, in
continuo sviluppo, sia per usi professionali che domestici.
Una delle principali e più recenti innovazioni portate dal nuovo millennio,
relativa all'uso delle GPU, è stata il
GPU (GPGPU).
General Purpose Computing on
Quest'ultimo nasce dall'idea di porre l'intenso parallelismo e l'elevata
potenza di calcolo, messi a disposizione dalle GPU, al servizio, non solo di
applicazioni grache, ma anche di applicazioni general purpose, che vanno
da un uso scientico ad uno puramente più commerciale.
In tale ambito di utilizzo la GPU viene impiegata per elaborazioni
estremamente esigenti in termini di potenza di calcolo, e per le quali le
tradizionali architetture di CPU non hanno una capacità suciente.
Tale tipo di elaborazioni sono, per loro natura, di tipo altamente parallelo,
e in grado quindi di beneciare ampiamente dell'architettura tipica delle
GPU.
A tale caratteristica intrinseca, negli ultimi tempi si è aggiunta l'estrema
CUDA e
OpenCL), che al succedersi delle generazioni aumentano non solo la
programmabilità oerta dalle ultime soluzioni commerciali (
propria potenza elaborativa ma anche la propria versatilità.
13
Figura 11: Partendo dall'alto: Slot PCI Express x4, x16, x1, x16 e uno slot
PCI tradizionale a 32 bit
3.2 Architettura e Parallelismo
Per comprendere al meglio la seguente sezione, analizzeremo l'architettura
di un generico processore graco moderno, in Figura 12.
Figura 12: Architettura di una GPU moderna
Le GPU sono coprocessori e in quanto tali devono essere connesse ad un
processore tradizionale, chiamato
Host.
Generalmente il collegamento tra i dispositivi è realizzato con un bus PCI
Express ad alta velocità, che consente il trasferimento di dati dalla memoria
della GPU a quella della CPU e viceversa.
In architetture particolari, quali ad esempio gli smartphone, invece, ci sono
veri e propri
System-on-Chip che incorporano tutti gli elementi in unico
package, in modo da massimizzarne la velocità di comunicazione.
14
Le GPU dispongono di un alto grado di parallelismo, in particolare nella
struttura dei diversi dispositivi di memorizzazione e nella disposizione dei
core d'esecuzione.
Ogni GPU è composta da diverse unità di elaborazione, chiamate
Streaming Multiprocessor (SM), che rappresentano il primo livello
logico di parallelismo.
Ogni SM è a sua volta suddiviso in un gruppo di
Streaming Processor
(SP), ognuno dei quali è un core d'esecuzione reale, in grado di eseguire
sequenzialmente un thread.
Gli SM sono a loro volta organizzati in una serie di
CLuster (TPC).
Thread Processing
Figura 13: Da sinistra, la struttura di un SM e quella di un TPC
In Figura 13, a sinistra è mostrata la struttura di un SM, contenente al suo
interno 8 processori scalari, una memoria condivisa, registri, 2 unità (SFU)
dedicate all'esecuzione di funzioni speciali e una DPU, un'unità dedicata al
calcolo in precisione doppia.
A destra è invece mostrato un esempio di Thread Processing Cluster,
formato da 3 SM, con memorie cache condivise tra il TPC e memorie
dedicate alla gestione di texture.
In questo senso l'architettura di una GPU rientra nella classicazione SIMD
(Single Instruction Multiple Data), in quanto una singola istruzione viene
eseguita parallelamente da più unità di elaborazione che operano su insiemi
di dati diversi.
Lo Streaming Multiprocessor gestisce una serie di thread raggruppandoli in
unità chiamate
warp.
Ogni Thread all'interno di un warp esegue lo stesso insieme di istruzioni in
maniera del tutto indipendente, richiedendo però che tale esecuzione sia
sincronizzata.
Infatti è presente una forma di sincronizzazione forzata (lockstep ), adata
ad un componente chiamato
warp scheduler.
Ogni GPU ha a disposizione diversi tipi di memoria, ognuna delle quali è
localizzata in dierenti aree del dispositivo, possiede caratteristiche diverse
e può essere utilizzata per compiti dierenti.
L'unità di memoria più capiente è la cosiddetta memoria globale, che nelle
GPU di ultima generazione raggiunge dimensioni di diversi GB e comporta
una latenza piuttosto elevata.
Tutti i Core della GPU possono accedere a questo spazio di memoria, così
come può fare anche l'host, collegato direttamente al dispositivo di
15
memorizzazione.
Non essendo particolarmente veloce, la memoria globale spesso dispone di
meccanismi di ottimizzazione degli accessi o di livelli di cache, che
consentono una comunicazione più eciente.
Un altro spazio di memoria condivisa da tutti i core è la texture memory,
utilizzata dal processore graco in sola lettura.
Questo tipo di memoria dispone di specici meccanismi di caching che la
rendono eciente nella memorizzazione di strutture bidimensionali (matrici
o immagini) e nell'accesso ad elementi spazialmente vicini.
All'interno di ogni SM, inoltre, è presente uno spazio di memoria condiviso
tra i core che compongono un gruppo di lavoro.
Questa memoria è decisamente più veloce di quella globale ma ha
dimensioni molto più ridotte, dell'ordine di qualche decina di MB per ogni
SM, e viene genericamente utilizzata per memorizzare valori che devono
essere usati più volte, da core diversi, limitando il numero di accessi in
memoria globale.
Gli aspetti negativi della condivisione di questo spazio di memoria
riguardano la loro coerenza, che deve essere mantenuta per evitare l'uso di
valori errati o non più validi.
Inne, ogni SM dispone di un certo numero di registri interni, che
rappresentano uno spazio di memorizzazione locale, ad accesso rapido e di
dimensioni limitate, che consentono la memorizzazione di valori
frequentemente usati da un singolo core.
Esempio: Architettura NVIDIA Fermi Come esempio di prodotto
commerciale presentiamo l'architettura NVIDIA Fermi.
Figura 14: Architettura NVIDIA Fermi
Al suo interno sono presenti 16 Streaming Multiprocessor e il supporto di
una quantità di memoria DRAM no a 6GB GDDR5 (Graphics Double
Data Rate).
16
La GPU è connessa alla CPU tramite un bus PCI Express 2.0 x16 ad alta
velocità (no a 8 GB/s).
All'interno di ogni SM troviamo 32 core (SP), che permettono a
quest'architettura di usufruire in parallelo di un massimo di 512 Cuda
Cores (16 SM x 32 SP).
É inoltre presente una memoria condivisa, cache L1 da 64 KB totali, per
permettere la comunicazione tra i diversi threads, ed una L2, sempre
condivisa, di 768 KB.
L'architettura Fermi dispone di un Dual Warp Scheduler, che permette
l'esecuzione di due warp concorrentemente, delegando ciascuna istruzione di
essi ad un gruppo di 16 core.
La frequenza di clock di 1.5 GHz permette di raggiungere una prestazione
massima di 1.5 TFlop/s, con una larghezza di banda di 192 GB/s.
Figura 15: Struttura SM dell'architettura Fermi
17
3.3 Modelli di Programmazione
Il paradigma di programmazione che caratterizza il calcolo su GPU è
chiamato
Stream Processing, perché i dati possono essere visti come un
usso omogeneo di valori ai quali vengono applicate in maniera sincrona le
stesse operazioni.
Le funzioni che processano i dati nello stream e che sono eseguite sulla
GPU prendono il nome di kernel e svolgono un insieme abbastanza limitato
di operazioni su ogni usso di dati.
•
Operazioni di copia : tutti gli elementi sono copiati da uno stream ad
un altro.
•
Operazioni di ltraggio : alcuni elementi di uno stream sono selezionati
in base a determinate caratteristiche e copiati.
•
Operazioni di accesso : si accede ad uno specico elemento dello
stream utilizzando un indice.
•
Operazioni di calcolo : vengono eettuati calcoli sugli elementi di uno
stream.
In tale modello di programmazione, un main è in esecuzione sull'host
(CPU) e gestisce il parallelismo assegnando le varie istanze del kernel a
stream diversi.
La struttura di funzionamento di un kernel segue quasi sempre uno schema
preciso.
Innanzitutto viene caricato nella memoria della GPU un usso di dati
(input) sul quale il kernel applica una serie di operazioni che producono un
usso di dati in uscita (output).
Sarà poi compito dell'host prelevare l'output generato dalla GPU
accedendo alla sua memoria globale.
Il grande aumento di performance presentato dalle GPU nell'ultimo
decennio, come già sappiamo, ha spinto il mondo scientico a fare uso di
questi dispositivi anche per la risoluzione di problemi General Purpose
(GPGPU).
Questo ha consentito la nascita e il rapido sviluppo di diversi linguaggi di
programmazione per l'ambiente graco.
Il GPGPU ha preso veramente il via quando, nel 2006, vennero presentati
CUDA e Stream, due interfacce per la programmazione graca progettate
rispettivamente da NVIDIA e AMD.
Qualche anno più tardi nacque anche il progetto
OpenCL, con lo scopo di
realizzare un framework d'esecuzione eterogeneo sul quale potessero
lavorare sia GPU che CPU.
Col passare del tempo questi linguaggi si sono evoluti a tal punto da essere
simili ai diusi linguaggi di programmazione general purpose quali C, C++,
Java, Fortran e simili.
Tuttora CUDA e OpenCL rappresentano le soluzioni più ecienti e diuse
per la programmazione general purpose di processori graci.
CUDA
CUDA, acronimo di
Computer Unifed Device Architecture,
è un framework ideato da NVIDIA nel 2006. É un'architettura di calcolo
parallela general purpose che fornisce un'interfaccia di programmazione
18
(API) orientata al calcolo, senza esplicito riferimento ad operazioni grache,
nonché un compilatore apposito (
nvcc).
Nel toolkit CUDA è presente anche un ambiente di sviluppo integrato
(
Nsight) ed una serie di librerie specializzate come cuBLAS
per svolgere
operazioni di algebra lineare, cuSPARSE per lavorare su matrici sparse,
cuFFT per il calcolo della Fast Fourier Transform e THRUST, che è
essenzialmente una versione della STL del C++ ottimizzata per GPU.
Nonostante CUDA sia una soluzione proprietaria, non è detto che tutte le
GPUs che supportano tale framework abbiano la stessa architettura.
É possibile, infatti, che esse dieriscano ad esempio per il numero di core
presenti sul chip.
Per evitare eventuali problemi di portabilità delle applicazioni, NVIDIA
propone con CUDA un modello altamente scalabile in grado di adattarsi
senza dicoltà a tutti i chip graci che supportano tale framework.
Figura 16: Struttura scalabile del paradigma CUDA
L'idea di base è quella di suddividere il carico di lavoro partizionando un
programma multithread in una serie di blocchi paralleli ed indipendenti tra
loro formanti una griglia e contenenti i vari threads.
In questo modo ogni programma compilato in CUDA si adatterà runtime
all'architettura su cui è in esecuzione, in modo del tutto trasparente
rispetto al numero di core presenti.
Il programmatore, infatti, setta una congurazione di esecuzione su un
certo numero di blocchi, ma solo a tempo di esecuzione la suddivisione
logica in blocchi corrisponderà all'assegnazione sica agli Streaming
Processors presenti sulla GPU, come mostrato in Figura 16.
E' facile intuire che se un chip graco possiede più SM rispetto ad un altro,
esso elaborerà i processi in maniera più rapida.
La griglia di blocchi in cui è diviso il programma può essere
monodimensionale (vettore) o bidimensionale (matrice).
Per quanto riguarda il singolo blocco, possiamo trovare una struttura
monodimensionale, bidimensionale o tridimensionale (cubo) di thread (no
ad un massimo di 1024 unità).
19
Nell'esecuzione i blocchi sono indipendenti tra loro, mentre i thread a loro
appartenenti cooperano accedendo agli stessi dati e processandoli in
maniera sincrona.
A ciascun blocco e a ciascun thread è associato un ID che ne permette
l'identicazione.
Figura 17: Struttura dei blocchi in CUDA
La gerarchia di thread, presente nel paradigma di programmazione CUDA,
permette anche una gestione più eciente dei vari strati di memoria.
Infatti, come mostrato in Figura 18, anche le memorie assumono una
struttura gerarchica.
Ogni thread ha un'area di memoria locale, privata e non condivisa.
Per ogni blocco, viceversa, c'è una memoria condivisa (Shared Memory ),
accessibile da tutti i suoi thread.
Inne, è presente un'area di memoria globale, sempre condivisa ed
usufruibile da tutti i thread della griglia.
In conclusione, la piattaforma CUDA è progettata per essere utilizzata
esclusivamente con processori graci prodotti da NVIDIA, caratteristica che
ne limita l'impiego in misura considerevole.
D'altra parte questo vincolo si trasforma in vantaggio qualora si prendono
in considerazione le prestazioni, che sono indiscutibilmente migliori, data la
nativa predisposizione di questo paradigma per architetture NVIDIA.
20
Figura 18: Divisione memorie in CUDA
OpenCL
OpenCL (
Open Computing Language) è un framework per
lo sviluppo di applicazioni eseguibili su architetture eterogenee progettate
in maniera indipendente rispetto all'hardware scelto.
Infatti è possibile eseguire il codice su dispositivi come CPU, GPU, DSP e
FPGA, anche se prodotti da aziende diverse.
Questa soluzione, sviluppata e tenuta in commercio da un consorzio
no-prot chiamato Khronos Group è l'alternativa principale al framework
proposto da NVIDIA nel campo del GPU computing (CUDA).
Tuttavia, OpenCL basa la sua strategia di mercato su un'idea radicalmente
opposta a quella usata da CUDA.
Infatti mentre quest'ultima propone come suo punto di forza la
specializzazione dei prodotti (architettura ideata, sviluppata e compatibile
solo con NVIDIA) garantendo ottime prestazioni a discapito della
portabilità su architetture diverse, OpenCL invece propone una soluzione
compatibile con più dispositivi plurimarche presenti sul mercato, come ad
esempio Intel, NVIDIA, IBM e AMD, ma con prestazioni inferiori.
Il modello di programmazione di OpenCL per alcuni versi è molto simile al
paradigma introdotto da CUDA, a meno dell'uso di una dierente
terminologia.
Richiede la presenza di un processore
Device.
Host collegato ad uno o più OpenCL
Compute
Units, che a loro volta devono essere viste come una serie di Processing
Element.
Ciascun device, inoltre, deve essere inteso come un aggregato di
Considereremo come Device una GPU, così da associare gli elementi
studiati nel paradigma CUDA, con i corrispondenti OpenCL.
In particolare, le Compute Unit coincidono con gli Streaming
Multiprocessor e i Processing Element con gli Streaming Processor.
21
Figura 19: Architettura OpenCL
Il modello di esecuzione proposto da OpenCL si presenta diviso in due parti:
il programma Host eseguito dalla CPU e il
kernel eseguito dalle Device.
Un principio fondamentale su cui si basa tale paradigma è che il kernel deve
essere sempre denito all'interno del contesto gestito dall'Host.
Il contesto comprende:
•
Device accessibili dall'host.
•
Funzioni Kernel con il valore dei relativi argomenti, tutti contenuti
all'interno di strutture chiamate Kernel object.
•
Program objects, consistente del codice sorgente e dell'eseguibile del
programma che implementa il Kernel.
•
Memory objects, ovvero una serie di oggetti di memoria visibili
all'host e alle devices durante l'esecuzione del kernel.
Le interazioni tra Host e Device avvengono attraverso le code di comandi
command-queue), le quali vengono associate una ad ogni device.
(
I comandi che possono essere inviati dall'Host si dividono in 3 categorie:
kernel enqueue commands (comandi per l'inserimento in coda di un
kernel), memory commands (comandi per il trasferimento di dati tra
host e device) e synchronization commands (comandi per la
sincronizzazione dell'esecuzione).
La coda di comandi può essere risolta sia seguendo l'ordine di ricezione
in-order execution) e sia in maniera random (out-of-order execution).
(
Nell'istante in cui viene inviato il comando di esecuzione di un kernel viene
denita anche la sua matrice di esecuzione, ovvero uno spazio di indici
N-dimensionale denominato
NDRange (N-Dimensional Range con
N=1,2,3), la quale permette di suddividere ecientemente l'onere
computazionale sul device.
Infatti un kernel object, viene eseguito in un numero variabile di
work-group, contenenti a loro volta i work-item, ovvero le istanze di
esecuzione del kernel.
E' possibile identicare i work-item o tramite un ID globale o tramite una
coppia di ID formata dall'ID del work-group e dall'ID locale del work-item
all'interno del gruppo.
22
Il programmatore può denire l'NDRange tramite 3 vettori di interi:
•
Grandezza dello spazio globale in ciascuna dimensione (G);
•
Un oset che setta il valore iniziale degli indici in ciascuna dimensione
(F);
•
La grandezza dei work-group in ogni dimensione (S);
Figura 20: Esempio di NDRange
L'operazione di suddivisione del carico di lavoro in diversi work-group,
tenendo conto della capacità di calcolo parallelo del dispositivo in uso,
risulta essere uno dei parametri essenziali per il raggiungimento di ottime
performance durante l'esecuzione delle applicazioni.
Questa organizzazione elaborativa, inoltre, comporta una gerarchia di
private
memory e sia un accesso alla local memory, condivisa da tutti gli
memoria piuttosto particolare: ogni work-item possiede sia una
elementi appartenenti al work-group.
memoria
globale e sia ad una riservata alle costanti (global/constant memory),
Inoltre ogni work-item è in grado di accedere sia ad un'area di
entrambe condivise da tutti i devices presenti in uno stesso contesto.
Confronto tra CUDA e OpenCL
Avendo analizzato con cura
entrambi i framework, adesso è possibile discutere sia delle loro forti
analogie che delle sostanziali dierenze.
Come evidenziato dalla tabella di Figura 21, alcuni elementi dei due
framework ricoprono lo stesso ruolo, ma hanno una terminologia dierente.
Un aspetto fondamentale da tener conto è la
Portabilità.
Mentre l'utilizzo di CUDA è limitato a determinate architetture, tutte
rigorosamente di casa NVIDIA, OpenCL risulta altamente versatile,
permettendo la sua applicazione anche ad architetture eterogenee con
molteplici dispositivi, quali: CPU, GPU, DSP o FPGA.
23
Figura 21: Terminologia a confronto: CUDA e OpenCL
A suo vantaggio CUDA presenta una maggiore faciltà di programmazione,
proponendo al mercato un tool molto più maturo rispetto ad OpenCL,
contenente un proprio compilatore, un debugger e diverse librerie dedicate.
La presenza del compilatore nvcc, presente nel framewok di casa NVIDIA,
inoltre, consente una compilazione statica, molto più performante rispetto
alla compilazione run-time di OpenCL.
In denitiva, come sempre accade in informatica, non è possibile decretare
un assoluto vincitore nel confronto tra CUDA e OpenCL.
Entrambi presentano pro e contro, e possono essere più o meno preferiti da
programmatori diversi.
Infatti, hanno importanza fondamentale, nella scelta del paradigma,
l'hardware a disposizione, gli obiettivi preposti e il giudizio del
programmatore, ricordando che ogni kernel non sarà mai eseguito con le
stesse prestazioni su diverse architetture e che quindi tale scelta può variare
di caso in caso.
24
4 FPGA
In elettronica digitale, un dispositivo
Field Programmable Gate Array,
solitamente abbreviato in FPGA, è un circuito integrato le cui funzionalità
sono programmabili via software.
Tali dispositivi consentono l'implementazione di funzioni logiche anche
molto complesse e sono caratterizzati da un'elevata scalabilità.
4.1 Storia
Ross Freeman e Bernie Vonderschmitt, fondatori della compagnia Xilinx,
inventarono il primo circuito FPGA nel 1984, mentre ancora lavoravano per
la Zilog.
Tale circuito FPGA era composto solo da poche migliaia di porte logiche e
presentava parecchi svantaggi rispetto ai rivali di mercato, ovvero i
dispositivi ASIC.
In particolare, erano più lenti, consumavano maggior energia e
supportavano poche funzionalità.
L'industria dei circuiti FPGA crebbe, seppur lentamente, durante gli anni
'90, con la realizzazione, da parte del U.S. Naval Surface Warfare
Department , di un dispositivo contenente ben 600.000 porte logiche.
Fino ad allora, la maggior applicazione di questi circuiti rivoluzionari fu nel
campo del Networking e della Telecomunicazione.
Con l'arrivo del nuovo millennio, i circuiti FPGA evolsero no a contare
Milioni di porte logiche, coprirono una più vasta gamma di applicazioni
dierenti e risolsero i principali difetti che li rendevano svantaggiosi rispetto
ai dispositivi ASIC.
Inoltre, presentavano un'elevata capacità di parallelizzazione e pipelining
dei processi, che li rendeva adatti allo svolgimento dei compiti che la CPU
aveva dicoltà a gestire.
4.2 Origini - PLA e CPLD
Programmable
Logic Arrays (PLA) e Complex Programmable Logic Devices
L'idea del circuito FPGA ha origine da due dispositivi:
(CPLD).
Figura 22: Architettura PLA
I PLA furono introdotti circa nel 1970 come chip programmabili one-time
(solo una volta) con lo scopo di realizzare una particolare funzione logica.
25
Il procedimento di programmazione consisteva nel bruciare dei fusibili posti
in prossimità delle porte logiche (AND o OR), al ne di implementare la
tabella della verità desiderata.
I fattori limiti di questa tecnologia erano il numero di input, AND o OR,
presenti.
I CPLD, invece, nacquero successivamente, dall'idea di evolvere la struttura
di un dispositivo PLA introducendo una matrice di interconnessione tra
tutti gli input e output, realizzata tramite l'uso di una on-chip ash
memory (memoria ash su unico chip).
Tale matrice di interconnessione permette la congurazione delle
macrocelle, aventi una struttura simile ad un PLA, al ne di realizzare
qualsiasi funzione logica.
Figura 23: Architettura CPLD
26
4.3 Architettura
Il Field Programmable Gate Array è un dispositivo semiconduttore
comprensivo di molti blocchi logici con interconnessioni congurabili tra
loro.
Tali blocchi logici sono capaci di agire come semplici porte logiche, ad
esempio AND o OR, e in più presentano dei canali d'instradamento,
programmabili, che ne permettono la connessione.
Negli ultimi anni è cresciuto il numero di circuiti implementati attraverso la
tecnologia FPGA per applicazioni special purpose, ad esempio i DSP e i
moltiplicatori.
Le componenti principali dei dispositivi FPGA sono i blocchi logici, presenti
in milioni di unità e organizzati in un'unica grande rete all'interno del chip.
Questi sono implementati in a Lookup Table (LUT), spesso consistente di 4
pin di input.
Le LUT hanno una piccola porzione di memoria programmata per
impostare le dipendenze tra la logica di uscita e quella di entrata,
essenzialmente una tabella della verità .
Figura 24: LUT a tre ingressi
Ogni LUT ha una sola uscita, che può essere memorizzata all'interno di un
ip op, al ne di preservarne il valore oltre il singolo ciclo di clock e per
riutilizzarlo all'interno di una successiva logica implementativa.
I canali di instradamento che corrono lungo i dierenti blocchi logici sono
utilizzati per collegare varie LUT tra di loro.
Figura 25: Switch Block
27
Questi sono controllati da uno Switch Block (Figura 25 ), ovvero un blocco
di interruzione che ne permette la programmazione.
Tali connessioni permettono di programmare un immenso numero di logiche
dierenti e, di conseguenza, realizzare qualsiasi tipo di funzionalità.
Figura 26: FPGA Routing
Nelle nuove generazioni di dispositivi di FPGA sono stati introdotti altri
blocchi per la realizzazione di nuove speciche funzioni.
Quest'ultime vengono eseguite da tali blocchi specializzati, anche chiamati
Slices, molto più velocemente rispetto al caso in cui l'implementazione
avviene per via delle LUT e della rete di interconnessione.
Moltiplicatori e i dispositivi
DSP, i quali permettono ai dispositivi FPGA di essere più semplici e
Due dei principali blocchi oggi diusi sono i
contenere un numero inferiore di LUT.
Figura 27: Slices Specializzati
28
Per concludere la discussione sull'architettura dei dispositivi FPGA ne
mostriamo, in Figura 28, uno degli ultimi di casa Xilinx: il
Figura 28: Virtex-7
29
Virtex-7.
5 Ecienza Energetica
Finora, quest'elaborato ha trattato le architetture eterogenee, denendone
l'utilità e le proprietà, focalizzandosi sulle tre componenti principali e
analizzandone dettagliatamente evoluzione ed architettura.
Nella sua parte nale, l'elaborato si concentra sulle tecniche che permettono
l'uso di queste architetture in condizioni di Ecienza Energetica.
5.1 Energy Ecient System Design
I sistemi embedded, quali smartphone, tablet o portatili, sono esempi
perfetti di architetture eterogenee, realizzate con le tecnologie mostrate
precedentemente, che devono soddisfare restringenti vincoli, quali: risorse
limitate di energia e sistemi di rareddamento.
Tali fattori obbligano, in fase di progettazione, ad una particolare
attenzione all'energia dissipata dal dispositivo, così come al calore da esso
Energy Eciency il principale requisito da
raggiunto, rendendo l'
soddisfare.
In Figura 29, un graco nel quale si riassumono (per processori dierenti
tra loro) i requisiti di ecienza per due applicazioni particolarmente diuse
sui dispositivi mobili: comunicazione Wireless e HD Video.
Figura 29: Esempio di Energy Eciency in applicazioni Wireless e HD Video
Per raggiungere la massima ecienza possibile, sia energetica che in
performance computazionali, la scelta architetturale ricade sicuramente
sull'uso di Application Specic Integrated Circuits (ASIC).
Il problema di questa soluzione è la totale mancanza di essibilità, a causa
della quale il requisito di cambiamento-veloce, voluto dalla continua
innovazione richiesta dal mercato, non è soddisfatto.
Per questo motivo è nata l'esigenza di utilizzare piattaforme programmabili
(GPP, GPU, FPGA), capaci di soddisfare, seppur con minor ecienza,
tutti i requisiti di un tipico dispositivo embedded.
Il gap energetico tra un un processore General Purpose (GPP) ed un
Application Specic Integrated Circuit (ASIC) è enorme, anche di svariati
ordini di grandezza.
La causa principale di inecienza nei processori è il controllo dell'overhead.
In un processore, le risorse generiche sono controllate da istruzioni che
eseguono calcoli per dierenti tipi di applicazioni.
30
Paragonato con un ASIC, tale essibilità comporta un overhead molto
elevato.
Per fortuna in informatica non tutto è assoluto ed esistono tecniche capaci
di ottenere, sempre con l'uso di piattaforme di calcolo programmabili, un
miglior compromesso tra ecienza e essibilità.
Tale equilibrio è ricercato non solo nell'architettura e nell'hardware, ma
anche ottimizzando il software, con particolare attenzione alla fase di
compilazione.
Infatti, per una piattaforma programmabile, il compilatore è cruciale.
Se mal progettato può incidere pesantemente sull'ecienza del dispositivo,
viceversa può incrementarne la produttività.
Inoltre, lo sfruttamento a pieno di un processore dipende anche dalla
qualità del codice generato dal compilatore.
L'ottimizzazione realizzata da quest'ultimo può avere un grande impatto
sui consumi energetici ed è la chiave della progettazione di architetture
embedded Low-Power .
5.2 Consumo Energetico
Le piattaforme embedded spesso sono costruite utilizzando circuiti digitali
CMOS, pertanto è fondamentale combinare tecniche legate al livello
architetturale con quelle associate al livello circuitale.
Per poter sfruttare a pieno il potenziale del paradigma low-power, le
architetture e i sistemi software includono sistemi operativi e compilatori
capaci di utilizzare opportune tecniche, quali il
Scaling della Frequenza (DVFS).
Voltaggio Dinamico e lo
Nei circuiti CMOS, la maggior parte dell'energia è dissipata al cambio della
porta di uscita.
Il consumo di energia di tali circuiti può essere determinato con la formula
dell'equazione:
P = αCVdd2f + Ileak Vdd
Il primo termine rappresenta la dissipazione della componente dinamica del
circuito, con
fornito e
f
αC
la capacità di commutazione del circuito,
Vdd
il voltaggio
la frequenza.
Il secondo termine, invece, è la potenza dispersa, con
Ileak
la corrente di
dispersione.
La componente dinamica è tipicamente la maggior fonte di consumo
energetico.
2
Inoltre, la presenza del voltaggio elevato al quadrato (Vdd ) suggerisce che è
tale costante l'elemento di maggior peso nell'economia del dispositivo
CMOS.
Per questo motivo, una tecnica usata è quella di scalare il voltaggio
frequenza
f
(VFS - Voltage and Frequency Scaling ) per ridurre
notevolmente l'energia consumata.
31
Vdd
e la
Figura 30: Gap tra l'ecienza computazionale intrinseca (ICE) e l'ecienza
reale dei processori
Oltre alle tecniche che riducono direttamente l'energia consumata dal
circuito, è importante anche incrementare la porzione di energia spesa per lo
svolgimento di lavoro utile e quindi migliorare la Computational Eciency.
La Figura 30 mostra il valore di
Intrinsic Computational Eciency
(ICE) per dierenti tecnologie CMOS e il picco di performance ottenibile
da vari processori.
Tale valore rappresenta il potenziale grezzo del circuito CMOS, una realtà
ottenibile solo immaginando di costruire un circuito ad hoc per ogni
applicazione.
Sempre in gura, la linea più bassa nel graco rappresenta l'ecienza
computazionale raggiungibile con un processore general purpose (GPP), e
ne mostra l'eettiva distanza dal rispettivo valore ICE.
32
6 Energy Awareness nei Compilatori
Il compilatore è lo strumento che traduce il codice sorgente di alto livello
nel codice macchina della particolare architettura.
Gioca un ruolo fondamentale nello sviluppo del software, consentendo la
programmazione machine-indipendent e l'uso di linguaggi ad alto livello
quali il C/C++.
Storicamente, i compilatori si focalizzano sulla riduzione della dimensione e
l'aumento della velocità di generazione del codice.
Il requisito della
Energy Awareness è abbastanza nuovo, e per questo
ancora in via di sviluppo e perfezionamento.
Nella progettazione di sistemi a bassa-potenza (low-power), le tecniche che
permettono ottimizzazioni energy-aware giocano un ruolo fondamentale e
spesso sono correlate ad ottimizzazioni sulla velocità.
In questo capitolo verranno arontate alcune delle tecniche utilizzate dai
compilatori a supporto dell'ecienza energetica.
6.1 Riduzione attività di Switching
La commutazione dei circuiti è la principale causa di dissipazione di
potenza.
Sebbene un compilatore genericamente lavori ad alto livello, è capace di
inuenzare tale attività in larga misura e in molti modi diversi.
Per i motivi su citati, una delle prime prerogative di un compilatore è
quella di ridurre l'attività di commutazione, ad esempio, organizzando
attentamente le istruzioni di un'applicazione.
Negli ultimi anni sono stati presentati più articoli che proponevano una loro
soluzione per il raggiungimento di tale obiettivo.
Lee et al. proposero un algoritmo di scheduling per minimizzare l'attività
di switching riducendo la distanza di Hamming tra le istruzioni nei
processori VLIM, ottenendo una riduzione del 20% dell'attività
dell'instruction bus. [26]
Nel 2006, Shao et al. proposero un algoritmo di scheduling ciclico (loop)
sempre per processori VLIM che minimizzava sia la lunghezza del
programma che l'attività di switching con un miglioramento rispettivamente
del 11.5% e del 19.4% rispetto alla soluzione precedente. [29]
Sempre nel 2006, Diamond et al. presentarono una tecnica che combina la
codica e il riordino delle istruzioni, ottenendo un guadagno del 74% della
potenza dinamica senza avere alcuna perdita di prestazioni. [21]
Esistono molte altre tecniche, oltre a quelle elencate, che permettono di
ottenere miglioramenti energetici dalla fase di compilazione e che possono
riguardare sia l'organizzazione delle istruzioni che altri componenti interni
del processore, quali i registri e l'uso degli operandi.
6.2 Allocazione Risorse
Il compilatore è il responsabile della gestione di molte risorse del processore,
specialmente nel caso di sistemi embedded, nei quali la capacità di gestione
a tempo di esecuzione è limitata.
33
L'allocazione delle risorse ha un grande impatto sull'ecienza energetica di
un dispositivo, soprattutto nel caso in cui tali risorse consumano molta
energia, quali ad esempio il le Registro e le memorie in generale.
Per questi motivi, nei sistemi embedded spesso viene utilizzata la
Scratchpad Memory come alternativa alle cache.
Infatti, questa è una memoria ad alta velocità utilizzata per memorizzare
dati usati frequentemente dal processore.
É considerata molto simile alla cache di un processore, con la sostanziale
dierenza che, mentre la cache non è visibile al programmatore, la
scratchpad memory lo è.
Il compilatore alloca i dati nella scratchpad memory così da incrementare
sia le performance che il consumo energetico.
Avissar et al. presentarono uno schema per la gestione della scratchpad
memory, con il quale ottennero un miglioramento del 40% a tempo
d'esecuzione. [17]
Wehmeyer et al. mostrarono che l'inserimento della scratchpad memory nel
sistema di memorie permetteva un risparmio del 20% dell'energia nel
compilatore. [30]
Ayala et al. proposero una tecnica di compilazione power-aware, la quale
permette l'allocazione dei registri in modo tale da usare una sola parte del
le registro, e congurarne la restante in power-save mode (modalità di
risparmio energetico). Tale soluzione porta ad un risparmio energetico del
65% senza alcuna perdita in performance. [18]
Oltre alla Scratchpad Memory, un'altra memoria presente nei più comuni
processori embedded è il
Loop Buer.
Quest'ultimo è una memoria di piccola dimensione il cui scopo è contenere
un numero abbastanza ridotto di istruzioni, solitamente le istruzioni cicliche
più frequentemente eseguite.
É stato dimostrato che anche quest'ultima tecnica, utilizzata al posto di
comuni cache, consente una notevole riduzione dell'energia consumata.
6.3 Power-Management a Run-Time
I moderni microprocessori forniscono vari servizi per la gestione dell'energia
che possono essere controllati via software.
Un compilatore Energy-Aware deve essere capace di sfruttare tutti questi
servizi ottenendo un basso overhead in esecuzione.
Il
Dynamic Voltage and Frequency Scaling (DVFS) è un metodo
fondamentale per la gestione della capacità computazionale del processore
in ambiente a basso consumo energetico.
Wu et al. proposero un sistema di compilazione dinamica che ottenne una
sostanziale riduzione del consumo energetico del processore rispetto alla
tecnica DVFS, incrementando del 22% il prodotto
Energy-Delay (EDP).
[33]
You et al. presentarono una struttura capace di ridurre la potenza dispersa
(leakage power) nei microprocessori, utilizzando la tecnica del
Gating.
[34]
34
Power
6.4 Ottimizzazione dell'Instruction Set Architecture
(ISA)
In informatica, un
Instruction Set Architecture (ISA), (in lingua
italiana insieme d'istruzioni ), descrive quegli aspetti dell'architettura di un
calcolatore che sono visibili al programmatore.
Si tratta di fatto dell'insieme di istruzioni base che il processore può
compiere e che costituiscono dunque il suo linguaggio macchina, a partire
dal quale vengono scritti i relativi programmi nei vari linguaggi di
programmazione a più alto livello di astrazione.
Poiché l'Instruction Set Architecture (ISA) ha grande impatto sull'ecienza
del processore, un'approccio comune per la riduzione dei consumi energetici
è modicare l'ISA così da ottimizzare l'uso delle sue componenti più
ecienti.
Un esempio è quello di utilizzare istruzioni Complesse per ridurre il costo di
esecuzione di certi modelli di calcolo, migliorando le prestazioni e
risparmiando energia.
35
7 Conclusioni
7.1 Confronto tra architetture
L'esperienza quotidiana con i calcolatori insegna che l'elaborazione dei dati
e delle istruzioni dei programmi è compito specico della CPU.
I vari core che la compongono sono ottimizzati per l'esecuzione seriale delle
istruzioni, generando un usso di lavoro sequenziale.
Le GPU, per loro natura, utilizzano un metodo di lavoro completamente
opposto: anziché eseguire una sola operazione alla volta, ne portano avanti
diverse migliaia contemporaneamente (in parallelo).
Infatti la scheda graca ha molteplici unità di elaborazione, di grandezza e
potenza minore rispetto a quella di una CPU, ottimizzate per lavorare
parallelamente.
Le varie unità possono essere programmate per eseguire porzioni di codice o
programma anche di natura dierente grazie all'utilizzo degli
Shader.
In questo modo si è stati in grado di raggiungere un alto grado di ecienza
nella capacità di calcolo delle unità di elaborazione graca, che ha
invogliato la diusione di questa tecnologia anche per applicazioni general
purpose (GPGPU).
L'utilizzo massiccio delle GPU, anche per applicazioni di natura non graca
(GPGPU), caratterizzate da un'elevata parallelizzazione, può soddisfare la
richiesta di prestazioni sempre più spinte.
Va sicuramente precisato, però, che il GPGPU non è la soluzione denitiva
in questo senso.
Infatti, esistono processi che richiedono cooperazione e dipendenza tra i
dati, nonché numerosi salti condizionati, e che si prestano meglio ad
un'esecuzione su CPU multi-core, anziché su GPU.
Qui in seguito un breve confronto tra CPU e GPU:
•
Vantaggi Prestazionali.
Una GPU è capace di orire una maggiore capacità di elaborazione
rispetto ad un normale processore di pari fascia di potenza.
Cio è possibile, però, solo nel caso in cui il codice del programma è
ottimizzato per l'esecuzione parallela, e in tali casi, le GPU sono in
grado di garantire prestazioni anche 100 volte superiori a quelle delle
CPU.
36
•
Vantaggi sul Costo.
Non si notano grandi scostamenti tra CPU e GPU appartenenti alla
stessa fascia di mercato.
Ricordando, però, che la GPU ha circa 100 volte prestazioni superiori
alla CPU della stessa fascia è evidente come queste siano molto più
vantaggiose.
•
Tasso di Aggiornamento Tecnologico.
Al giorno d'oggi, le GPU vanno incontro ad aggiornamenti più
frequenti rispetto a quelli dei processori.
•
Consumo/Prestazione.
Anche se negli ultimi anni i produttori hanno lavorato molto
sull'ottimizzazione dei consumi energetici dei processori, le GPU
restano, nella maggioranza dei casi, più convenienti nel rapporto
consumi/prestazioni.
Come detto, infatti, accade molto raramente che la GPU raggiunga il
carico massimo di elaborazione, e di conseguenza, il picco di consumi
energetici.
Altra analisi meritano invece applicazioni sensibili, in alcuni casi real-time,
che richiedono un certo tasso di adabilità e di costanza nelle prestazioni.
Spesso queste problematiche vengono risolte con l'uso di tecnologie ad-hoc,
quali ASIP, ASIC o FPGA (quest'ultima nel caso in cui ha rilevanza anche
la essibilità del dispositivo), che permettono di raggiungere prestazioni
nettamente migliori, adattandosi specicamente alla risoluzione del compito
per cui vengono create.
Inoltre, la società attuale ricerca sempre più dispositivi performanti e, nel
caso di strutture mobili, energeticamente ecienti.
Questi due requisiti spesso sono contraddittori l'uno con l'altro.
Infatti, se si vogliono aumentare le prestazioni, è necessario dare maggior
potenza alle varie componenti elettroniche quali, per esempio, il processore,
il co-processore graco o il DSP, con un conseguente maggiore consumo
energetico.
Per questo motivo, tipicamente nei dispositivi di natura mobile, si ricerca
un compromesso tra prestazioni ed energia, sfruttando le abilità delle
piattaforme eterogenee trattate in quest'elaborato, per ricavare beneci da
ogni componente.
37
8 Bibliograa
1. Gordon E. Moore. Cramming more components onto integrated
circuits.
Electronics Magazine, 1965.
2. Wikipedia: Heterogeneous System Architecture,
http:
//en.wikipedia.org/wiki/Heterogeneous_System_Architecture
3. U.C. Berkeley CS267/EngC233: Applications of Parallel Computers
Lecture Notes,
http://www.cs.berkeley.edu/~demmel/cs267_Spr11/Lectures/
lecture01_intro_kay11.ppt
4. David B. Kirk and Wen-mei W. Hwu.
Programming Massively Parallel Processors: A Hands-on Approach.
Morgan Kaufmann Publishers Inc., 2010.
5. A. S. Tanenbaum, Architettura dei calcolatori.
Un approccio strutturale, Prentice Hall, 2006.
6. Alan Watt.
3d Computer Graphics. Addison-Wesley Longman Publishing Co.,
Inc., 1993.
7. GPGPU.org: General-Purpose computation on Graphics Processing
Units
http://gpgpu.org/
8. NVIDIA Fermi Computer Architecture,
http://www.nvidia.com/content/PDF/fermi_white_papers/
NVIDIA_Fermi_Compute_Architecture_Whitepaper.pdf
9. Acceleratori GPU Tesla,
http://www.nvidia.it/object/tesla-server-gpus-it.html
10. What is CUDA NVIDIA Developer Zone
http://developer.nvidia.com/what-cuda
11. OpenCL
http://www.khronos.org/opencl/
12. Wikipedia: OpenCL
http://en.wikipedia.org/wiki/OpenCL
13. FPGA Central, 2011.
http://www.fpgacentral.com/docs/fpga-tutorial/
history-programmable-logic
14. V.Betz, University of Toronto,
http:
//www.eecg.toronto.edu/~vaughn/challenge/fpga_arch.html
15. Electrical Engineering Times, October 2008.
http://www.eetimes.com/electrical-engineers/
education-training/courses/4000134/Fundamentals-of-FPGAs
38
16. M. Strickland, HEARST Electronic Products, 1 March 2010.
http://www2.electronicproducts.com/The_evolution_of_FPGA_
coprocessing-article-FAJH_FPGA_Mar2010-html.aspx
17. Oren Avissar, Rajeev Barua, and Dave Stewart.
An Optimal Memory Allocation Scheme for Scratch-Pad-Based
Embedded Systems.
ACM Transactions on Embedded Computing Systems (TECS), 2002.
18. Jose L. Ayala, Alexander Veidenbaum, and Marisa Lopez-Vallejo.
Power-Aware Compilation for Register File Energy Reduction.
International Journal of Parallel Programming, 2003.
19. James Balfour, William Dally, David Black-Schaer, Vishal Parikh,
and JongSoo Park.
An energy-ecient processor architecture for embedded systems.
Computer Architecture Letters, 2007.
20. Anantha P. Chandrakasan, Samuel Sheng, and Robert W. Brodersen.
Low-power CMOS digital design.
IEEE Journal of Solid-State Circuits, 1992.
21. Robert G. Dimond, Oskar Mencer, and Wayne Luk.
Combining Instruction Coding and Scheduling to Optimize Energy in
System-on-FPGA.
Proceedings of the 14th Annual IEEE Symposium on
Field-Programmable Custom Computing Machines (FCCM '06).
IEEE Computer Society, 2006.
22. Rehan Hameed, Wajahat Qadeer, Megan Wachs, Omid Azizi, Alex
Solomatnikov, Benjamin Lee, Stephen Richardson, Christos
Kozyrakis, and Mark Horowitz.
Understanding Sources of Ineciency in General-Purpose Chips.
Proceedings of the 37th Annual International Symposium on
Computer Architecture (ISCA '10). ACM, 2010.
23. Yifan He, Yu Pu, Richard Kleihorst, Zhenyu Ye, Anteneh Abbo,
Sebastian Londono, and Henk Corporaal.
Xetal-Pro: an Ultra-Low Energy and High Throughput SIMD
Processor.
Proceedings of the 47th Design Automation Conference (DAC '10).
ACM, 2010.
24. Mark Hill and Michael Marty.
Amdahl's Law in the Multicore Era.
Computer, 2008.
25. Chung-Hsing Hsu and Ulrich Kremer.
The Design, Implementation, and Evaluation of a Compiler
Algorithm for CPU Energy Reduction.
Proceedings of the ACM SIGPLAN 2003 Conference on Programming
Language Design and Implementation (PLDI '03). ACM, 2003.
26. Chingren Lee, Jenq Kuen Lee, Tingting Hwang, and Shi-Chun Tsai.
Compiler Optimization on VLIW Instruction Scheduling for Low
Power.
39
ACM Transactions on Design Automation of Electronic Systems
(TODAES), 2003.
27. Huzefa Mehta, Rober Michael Owens, Mary Jane Irwin, Rita Chen,
and Debashree Ghosh.
Techniques for Low Energy Software.
Proceedings of the 1997 International Symposium on Low Power
Electronics and Design (ISLPED '97).
IEEE, 1997.
28. Padmanabhan Pillai and Kang G. Shin.
Real-time Dynamic Voltage Scaling for Lowpower Embedded
Operating Systems.
Proceedings of the 18th ACM Symposium on Operating Systems
Principles (SOSP '01). ACM, 2001.
29. Zili Shao, Bin Xiao, Chun Xue, Qingfeng Zhuge, and Edwin H.-M.
Sha.
Loop Scheduling with Timing and Switching-Activity Minimization
for VLIW DSP.
ACM Transactions on Dessign Automation of Electronic Systems
(TODAES), 2006.
30. Lars Wehmeyer, Urs Helmig, and Peter Marwedel.
Compiler-optimized Usage of Partitioned Memories.
Proceedings of the 3rd Workshop on Memory Performance Issues
(WMPI '04). ACM, 2004.
31. Wikipedia. List of iOS devices.
http://en.wikipedia.org/wiki/List_of_iOS_devices
32. Michael Wolfe.
How Compilers and Tools Dier for Embedded Systems.
Proceedings of the 2005 International Conference on Compilers,
Architectures and Synthesis for Embedded Systems (CASES '05).
ACM, 2005.
33. Qiang Wu, Margaret Martonosi, Douglas W. Clark, V. J. Reddi, Dan
Connors, Youfeng Wu, Jin Lee, and David Brooks.
A Dynamic Compilation Framework for Controlling Microprocessor
Energy and Performance.
Proceedings of the 38th Annual IEEE/ACM International
Symposium on Microarchitecture (MICRO-38).
IEEE Computer Society, 2005.
34. Yi-Ping You, Chingren Lee, and Jenq Kuen Lee.
Compilers for Leakage Power Reduction.
ACM Transactions on Design Automation of Electronic Systems
(TODAES), 2006.
40