Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Piero Lanucara, Fabio Bonaccorso CASPUR Via dei Tizii,6b 00185 Roma Italy http://www.caspur.it E-mail:f.bonaccorso@caspur.it E-mail: p.lanucara@caspur.it
Matlab e Cuda: 2
Sommario
1. 2. 3. 4. 5. 6. La GPU La piattaforma CUDA Esecuzione di programmi CUDA Integrazione con Matlab attraverso i Mex file Jacket Esempi
Matlab e Cuda: 3
La GPU scarica la CPU per questi calcoli, raggiungendo un'efficienza non uguagliabile in software
Le vecchie GPU acceleravano operazioni 2d, oggi si occupano di tutto il processo anche nel 3d Hanno capacita' di calcolo intorno ai 1000 GFlop/s
Scuola Estiva di Calcolo Avanzato 2008
Matlab e Cuda: 4
Matlab e Cuda: 5
Matlab e Cuda: 6
Nella CPU molto hardware e dedicato al controllo del flusso di esecuzione e alla cache Architettura flessibile (general purpose)
Scuola Estiva di Calcolo Avanzato 2008
Nella GPU la maggior parte dellhardware e utilizzato per le molte unita' di calcolo Architettura dedicata (special purpose)
Matlab e Cuda: 7
GPU vs CPU
Una CPU (oggi) si sfrutta al massimo massimizzando l'utilizzo della cache
La cache avvicina i dati alla CPU
La memoria ha maggiore latenza e minore banda
Matlab e Cuda: 8
CUDA: Cos'e'
CUDA e unarchitettura hardware e software per sfruttare la potenza delle moderne GPU per il calcolo (scientifico)
Acronimo di Compute Unified Device Architecture
E' uno standard proprietario di NVIDIA E' multipiattaforma (C con estensioni + runtime)
Linux (32 e 64 bit) Windows (32 e 64 bit)
Scuola Estiva di Calcolo Avanzato 2008
Matlab e Cuda: 9
Il programma inizia sulla CPU (Host) La CPU esegue una parte di codice
Trasferimenti CPU<->GPU
Matlab e Cuda: 10
Matlab e Cuda: 11
Matlab e Cuda: 12
CUDA: Definizioni
Thread
Flusso di esecuzione indipendente I thread eseguono lo stesso codice su operandi diversi Ogni thread ha un ID univoco (threadIdx) Permette di selezionare i dati su cui opera il thread
Matlab e Cuda: 13
CUDA: Definizioni
La griglia CUDA e un gruppo di blocchi
Puo' essere un insieme lineare, 2D o 3D di blocchi Permette di mappare il problema in maniera naturale sui differenti blocchi Ogni blocco ha un ID univoco nella griglia (blockIdx)
CUDA e' progettato per lavorare efficientemente con un alto numero di threads La priorita e far calcolare tutti i processori Bisogna trovare la dimensione ottimale del blocco
Matlab e Cuda: 14
CUDA: Memoria
Condivisa (Shared) Accesso veloce
Visibile da tutti i threads di uno stesso blocco
Globale Accesso costoso (senza cache) Memoria visibile (lettura e/o scrittura) da tutti i threads Costante
Texture
Sfrutta unita' hw per operazioni di filtraggio
Matlab e Cuda: 15
Matlab e Cuda: 16
Alcune funzioni possono eseguire in modo asincrono La CPU puo' lavorare mentre la GPU esegue la chiamata
Matlab e Cuda: 17
CUDA: estensioni al C
Per definire un kernel CUDA si usa la parola chiave __global__ prefisso alla funzione. Esempio:
__global__ void vecAdd(float* A, float* B){
int i = threadIdx.x; B[i] = A[i] + B[i];
In questo modo, nvcc compila il codice per la GPU Le variabili su cui opera il kernel sono sulla GPU
Distinte da quelle sulla CPU Vanno trasferite prima di chiamare il kernel
Scuola Estiva di Calcolo Avanzato 2008
Matlab e Cuda: 18
CUDA: estensioni al C
Se in un kernel CUDA si vuole chiamare unaltra funzione, questa va dichiarata con la parola chiave __device__ Esempio:
__device__ float scalarAdd(float a, float b){
return a + b;
}
Scuola Estiva di Calcolo Avanzato 2008
Matlab e Cuda: 19
CUDA: estensioni al C
Per invocare il kernel nel codice si usa l'operatore <<< dimGrid, dimBlock >>> Esempio:
vecAdd <<<1 , N >>> (a_dev, b_dev);
La griglia e' da 1 blocco da N threads Per dimensionare le griglie e i blocchi CUDA c'e' un tipo nuovo, dim3 che specifica un vettore 1D, 2D o 3D
dim3 dimGrid1(10); dim3 dimGrid2(20,10); dim3 dimBlock1(3,3,3); // Griglia di 10 blocchi // Griglia di 20x10 blocchi // Blocco di 3x3x3 thread
Matlab e Cuda: 20
Matlab e Cuda: 21
Matlab e Cuda: 22
Tutti i processi di uno stesso blocco (fino alla completa esecuzione del kernel) possono leggere/scrivere la memoria condivisa Laccesso da parte dei threads di un blocco deve essere coordinato dal programmatore
Si utilizza la funzione __syncthreads() che rende visibile a tutti i thread una modifica alla memoria condivisa
Matlab e Cuda: 23
Matlab e Cuda: 24
In questa modalita nel kernel si possono usare funzioni di stampa, apertura file, ... non disponibili nellesecuzione sulla GPU
Scuola Estiva di Calcolo Avanzato 2008
Matlab e Cuda: 25
Librerie CUDA
La piattaforma CUDA viene fornita insieme a due librerie, che permettono di utilizzare implementazioni efficienti di algoritmi di base per il calcolo scientifico
CUBLAS CUFFT
Permettono unastrazione maggiore rispetto alla programmazione con i kernel CUDA Nella SDK ci sono numerosi esempi pronti per luso o da prendere a modello
Scuola Estiva di Calcolo Avanzato 2008
Matlab e Cuda: 26
La libreria e' in C
Vengono forniti i wrapper per il Fortran che si occupano anche dei traferimenti CPU<->GPU
Scuola Estiva di Calcolo Avanzato 2008
Matlab e Cuda: 27
La libreria e' in C
Vengono forniti i wrapper per il Fortran
Scuola Estiva di Calcolo Avanzato 2008
Matlab e Cuda: 28
CUDA stand-alone
Dopo aver compilato il programma CUDA, si lancia normalmente L'utilizzo della GPU puo' durare al piu' 5 sec
Altrimenti congela il monitor Si mette una scheda video secondaria
Matlab e Cuda: 29
Matlab e Cuda: 30
end do
Matlab e Cuda: 31
Matlab e Cuda: 32
CUDA: reduction
Una reduction e unoperazione che opera su un insieme di dati e restituisce un valore
Minimo, massimo, media, ecc. di un vettore
Matlab e Cuda: 33
Matlab e Cuda: 34
Matlab e Cuda: 35
Matlab e Cuda: 36
Matlab e Cuda: 37
Jacket e Matlab - 1
Jacket e un plugin per Matlab prodotto dalla AccelerEyes (ancora in betaversion).
Jacket, intervenendo ad un livello di astrazione notevolmente superiore ad altri strumenti analoghi, rimpiazza le strutture dati (originarie) di MATLAB, normalmente sulla CPU, in strutture dati sulla GPU. Tutte le operazioni saranno effettuate sulla GPU invece che sulla CPU (in modalit dataparallel). Alla fine del calcolo sar possibile riavere i dati sulla CPU utilizzando le funzionalit gi presenti in MATLAB.
Matlab e Cuda: 38
Jacket e Matlab - 2
Vediamo velocemente luso di Jacket con un primo esempio.
Per utilizzare Jacket dare (dalla linea comandi di MATLAB): >> addpath(/scratch/jacket/engine); Questo comando ci consente di utilizzare i files MEX presenti nella directory e corrispondenti a tutte le funzioni incluse in Jacket. Verifichiamo il nostro ambiente di lavoro: >> ginfo Jacket v0.4 (build ST67) data memory: 0mb used, 1491mb free GPU0 Quadro FX 5600, 1350 MHz, 1535mb VRAM, Capability 1.0
Matlab e Cuda: 39
Jacket e Matlab - 3
>> X=gsingle(magic(3)); >> Y=gsingle(ones(3)); >> A=X*Y A= 15 15 15 15 15 15 15 15 15 >> whos Name Size Bytes Class Attributes A 3x3 496 gsingle X 3x3 496 gsingle Y 3x3 496 gsingle
Matlab e Cuda: 40
Jacket e Matlab - 4
Loutput del comando whos mostra come la matrice A abbia lo stesso tipo delle matrici di input. Il calcolo (prodotto matriciale) stato effettuato, quindi, sulla GPU.
La funzione gsingle consente il cast di una matrice MATLAB in una matrice in singola precisione sulla GPU: >> A=gsingle(B); %push B to the GPU from the CPU
Per tornare indietro sulla CPU dobbiamo utilizzare la funzione builtin MATLAB double (o single): >> B=single(A); >> whos Name Size Bytes Class Attributes B 3x3 36 single
Matlab e Cuda: 41
Jacket e Matlab - 5
Le tecniche per vettorizzare un codice MATLAB mostrate in precedenza sono di aiuto per avere un codice efficiente sulla GPU. Lo stesso codice avr beneficio immediato dallutilizzo di Jacket. Codice vettorizzato MATLAB: >> tic;A=(ones(5000)+eye(5000));B=sqrt(A);max(max(B)),toc ans = 1.4142 Elapsed time is 1.487942 seconds. Le funzioni gones e geye creano due strutture dati sulla GPU analoghe alle funzioni builtin MATLAB. Codice Jacket: >> tic;A=(gones(5000)+geye(5000));B=sqrt(A);max(max(B)),toc ans = 1.4142 Elapsed time is 0.029784 seconds.
Matlab e Cuda: 42
Jacket e Matlab - 6
Non ce speranza di migliorare le prestazioni di un codice che esegue una serie di calcoli su variabili scalari, come quello sotto:
a=2.5;b=3.33;c=6.23; for i = 1:1000000
a=b+c; b=ac; c=b*a; if(a>b) a=bc; else b=b+12.3; end
End
Matlab e Cuda: 43
Jacket e Matlab - 7
Il prossimo esempio e la versione Jacket dello script benchdgemm utilizzato per testare le prestazioni del prodoto matriciale built--in in MATLAB. Il codice utilizzato e: addpath('/scratch/jacket/engine) % Warm-up GPU a = gsingle(rand(200)); b = a; c=a*b; gforce(c); % Begin bench icont=1; for n=128:32:2560 a = gsingle(rand(n)); b = a; tic; c=a*b; gforce(c); ttt=toc; jacket(icont) = (2*n^3-n^2)/(ttt*10^9); icont = icont+1; end v=128:32:2560; plot(v,jacket); xlabel('Matrix dimension') ylabel('GFLOP/s)
Matlab e Cuda: 44
Jacket e Matlab - 8
Osservazioni sullo script: Nel modello di programmazione di CUDA e possibile che il calcolo sulla GPU sia dilazionato di modo che questo venga effettuato solo quando il risultato e necessario. La funzione gforce viene utilizzata per forzare il calcolo sulla GPU. In generale puo essere utilizzata per ottimizzare un codice Jacket. E buona norma riscaldare" la GPU chiamando una prima volta la parte di codice di cui vogliamo misurare le prestazioni. Questo consentira di precaricare le librerie per poter prendere il massimo delle prestazioni dal calcolo. Mandiamo in esecuzione il codice: >> addpath('/scratch/jacket/engine'); >> benchdgemm_jacket
Matlab e Cuda: 45
Jacket e Matlab - 9
Come si vede le prestazioni sono eccellenti, con cambiamenti minimi rispetto alla versione Matlab
Scuola Estiva di Calcolo Avanzato 2008
Matlab e Cuda: 46
Matlab e Cuda: 47