TESI DI LAUREA TRIENNALE IN GPU-CUDA ENVIRONMENT Università degli Studi di Napoli – “Parthenope” Dipartimento di Scienze e Tecnologie Corso di Laurea in Informatica TESI DI LAUREA TRIENNALE RIMOZIONE DEL RUMORE DA IMMAGINI PESATE IN DIFFUSIONE UTILIZZANDO IL METODO “PCA LOCALE OVERCOMPLETE” IN AMBIENTE GPU-CUDA DIFFUSION WEIGHTED IMAGE DENOISING USING “OVERCOMPLETE LOCAL PCA” METHOD IN GPU-CUDA ENVIRONMENT Salve a tutti, come già annunciato dal professor Giunta presenterò un software efficiente per la rimozione del rumore da immagine mediche. Relatore: Dott. Livia Marcellino Laureando: Ivan Osato (0124/250) Anno Accademico 2013/2014 Ivan Osato - Università degli Studi di Napoli "Parthenope"
Sommario La struttura delle immagini DWI Il metodo PCA locale overcomplete Introduzione al GP-GPU Ambiente di sviluppo CUDA Il software parallelo sviluppato Test e risultati Conclusioni e Sviluppi futuri Inizierò introducendo quella che è la struttura delle immagini DWI. Per poi descrivere prima il metodo OLPCA ed in seguito le caratteristiche del software parallelo sviluppato. Terminerò esaminando i risultati sperimentali ottenuti. Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"
La struttura delle immagini DWI Le immagini DWI (Diffusion Weighted Images) sono immagini di risonanza magnetica (MRI) pesate in diffusione, capaci di misurare il moto microscopico delle molecole di acqua in un tessuto biologico, permettendo quindi l’analisi della microstruttura bianca cerebrale sia in condizioni normali che patologiche. La diffusione rappresenta il moto caotico e disordinato delle molecole di un mezzo, dovuto all’agitazione termica. L’elemento preponderante è l’acqua che comprende il 65-90% in volume dei tessuti biologici e svolge la funzione di mezzo di trasporto dei composti biochimici. Strutture con diffusione normale sono rappresentate convenzionalmente più scure (segnale di risonanza più attenuato) mentre laddove la velocità di diffusione è minore (ischemia) sono rappresentate più chiare. Le immagini DWI sono immagini di risonanza magnetica basate sul fenomeno della diffusione, che rappresenta il moto microscopico delle molecole di acqua in un tessuto biologico, permettendo quindi l’analisi della microstruttura bianca cerebrale sia in condizioni normali che patologiche. Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"
La struttura delle immagini DWI Il più recente sviluppo della DWI è rappresentato dall’imaging in tensore di diffusione (Diffusion Tensor Imaging, DTI), che è una tecnica che mette in evidenza non soltanto l’entità della diffusione delle molecole di acqua nei tessuti ma anche la direzione consentendo di superare i limiti di direzionalità di DWI. Le immagini DTI si ottengono attraverso l’acquisizione di immagini pesate in diffusione lungo diverse direzioni tramite l’applicazione di una sequenza EPI (Echo Planar Imaging), cui viene fatta seguire in successione una serie di gradienti con orientazioni variabili. Il più recente sviluppo delle immagini DWI è rappresentato dall’imaging in tensore di diffusione (DTI) che mette in evidenza non soltanto la diffusione delle molecole di acqua ma anche la loro direzione. Quindi di base le immagini DWI sono multicomponente (quindi tridimensionali) ma la direzione conferisce loro una quarta dimensione! slice (3D) direzioni (4D) Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"
La struttura delle immagini DWI Le immagini DWI hanno per natura, un basso SNR (Signal to Noise Ratio) a causa della scarsa ampiezza del segnale ed il pronunciato rumore termico. Questo basso rapporto rende l’analisi estremamente complessa, pregiudicando la stima dei parametri di diffusione quantitativi. Esistono diverse tecniche di denoising che possono migliorare la qualità dei dati DWI come step di post-elaborazione Queste immagini hanno un basso rapporto segnale rumore a causa della scarsa ampiezza del segnale e del pronunciato rumore termico che rende quindi l’analisi molto complessa. Esistono diverse tecniche di denoising per migliorare la qualità delle immagini ed un esempio è il metodo OLPCA utilizzato nel mio lavoro di tesi. METODO OLPCA Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"
Il metodo PCA locale overcomplete Il metodo PCA locale per la rimozione del rumore Rician da immagini DWI, sfrutta la ridondanza multi-direzionale delle immagini pesate in diffusione multicomponente, per ridurre localmente le componenti principali meno significative attraverso un approccio overcomplete. Questo metodo consente di rimuore il rumore Rician dalle immagini DWI sfruttando la ridondanza multi-direzionale delle immagini per ridurre localmente le componenti principali meno significative attraverso un approccio overcomplete Come funziona questo approccio? Ogni voxel viene elaborato localmente in una finestra locale che può sovrapporsi con la finestra locale dei voxel adiacenti. Queste sovrapposizioni generano più stime dello stesso voxel che deve essere quindi processato ulteriormente con una operazione di media pesata. L’elaborazione di ogni singolo voxel avviene localmente, all’interno di finestre locali che possono sovrapporsi a quelle dei voxel adiacenti. In seguito alla sovrapposizione delle patch (overlapping), elaborate separatamente, si ottengono diverse stime per alcuni voxel da processare attraverso una media (overcomplete). Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"
Il metodo PCA locale overcomplete La Principal Component Analysis (PCA, Analisi per Componenti Principali) è una trasformazione lineare ortogonale dei dati che vengono mappati in un nuovo sistema di riferimento ortogonale in modo da massimizzare la varianza (rispetto ad ogni altra proiezione) associata alla prima coordinata, poi quella associata alla seconda coordinata e così via. Le proiezioni, considerate nell’ordine, prendono il nome di componenti principali. . L’analisi per componenti principale è una trasformazione lineare ortogonale dei dati che vengono mappati in un nuovo sistema di riferimento ortogonale che massimizza la varianza associata alla prima coordinata, poi quella associata alla seconda coordinata e così via. Le proiezioni nell’ordine son chiamate componenti principali. Si parte da una matrice dei dati che ha tante colonne quante sono le osservazioni e tante righe quante sono le variabili del fenomeno esaminato, quindi la PCA consiste nel calcolare gli autovalori e gli autovettori della matrice di covarianza XTX dei dati centrati La PCA consiste nel calcolo degli autovalori e degli autovettori della matrice di covarianza XTX dei dati centrati: . Il primo autovettore di XTX è la prima componente principale, mentre il primo autovalore è la varianza associata a tale componente principale, che è la massima possibile. La varianza che rimane, è associata alle altre direzioni e quindi alle restanti componenti principali. Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"
Il metodo PCA locale overcomplete Per ogni punto xp con p = (i, j, z, k) nel dominio dell’immagine 4D, le patch 3D circostanti xp in ogni direzione K, sono riordinate come vettore colonna di una matrice X di (N x K) componenti (N elementi della patch x K direzioni). PER OGNI MATRICE X C = XTX Calcolo autovettori di C in W Y = XW Thresholding di Y in Ŷ con τ = γ * σ XD = ŶW-1 + μ PCA LOCALE Come funziona il metodo PCA locale overcomplete? Per ogni punto del dominio dell’immagine, si estra una patch 3D circostante xp in ogni direzione K. Queste patch costituiscono le colonne di una matrice X locale alla quale viene applicato il processo di PCA locale che consiste nel decomporre il segnale in componenti principali locali, rimuovere le componenti principali meno significative attraverso un’operazione di sogliatura e infine ricostruire il segnale nella matrice Xdenoised! Le colonne di questa matrice Xdenoised (attraverso l’overlapping) sono riposizionate nell’immagine di output nella posizione dove erano state estratte come patch3D dall’immagine rumorosa Per finire si effettua una media pesata che tiene conto delle sovrapposizioni tra le patch. OVERLAPPING DI XD Le colonne della matrice sono riposizionate nell’immagine di output (sommate ai valori già presenti), nella posizione dove erano state estratte come patch 3D dall’immagine rumorosa. MEDIA Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"
Flow-chart algoritmo sequenziale Questo è il diagramma di flusso dell'algoritmo OLPCA che prevede una fase di inizializzazione seguita da altre fasi di calcolo. Per ridurre i tempi di esecuzione, ho implementato un algoritmo parallelo realizzando un kernel per le parti colorate in (arancione, viola e verde). Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"
Introduzione al GP-GPU L’unità di elaborazione grafica (Graphics Processing Unit, GPU) è una tipologia particolare di coprocessore composto da più multiprocessori paralleli, organizzati secondo uno schema architetturale finalizzato al paradigma SIMD (Single Instruction Multiple Data). Queste unità nascono nell’ambito della Computer Graphics per l’esecuzione di operazioni grafiche (rendering) che lavorano su una grande quantità di dati. Le GPU (Graphic Processing Unit) sono microprocessori paralleli delle moderne schede video. Nascono nell’ambito della Computer Graphics per operazioni prettamente grafiche di rendering, Ma poi si sono evolute per il General Purpose per la risoluzione di problemi generici La GP-GPU (General Purpose Computing on GPU), si propone di impiegare le GPU per applicazioni parallele High Performance General Purpose, sfruttando le loro capacità di elaborazione in parallelo per compiti che vanno oltre la Computer Graphics. Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"
Ambiente di sviluppo CUDA Come usare un ambiente ideato per la grafica in applicazioni General Purpose? NVIDIA ha modificato la GPU rendendola interamente programmabile per le applicazioni scentifiche e aggiungendovi il supporto per linguaggi ad alto livello come C e C++ nell’ambiente di sviluppo CUDA. Per realizzare applicazioni General Purpose si può utilizzare l’ambiente di sviluppo NVIDIA CUDA che considera la CPU e la GPU come due macchine separate che eseguono rispettivamente codice sequenziale e parallelo. Questa architettura prevede differenti tipi di memoria condivise e non con diverse latenze d’accesso. E’ compito del progettista realizzare una strategia che mira ad utilizzare in maniera efficiente queste memorie. Il modello architetturale CUDA considera la CPU e la GPU come due macchine distinte dette host e device, che eseguono rispettivamente la parte di codice sequenziale e parallela (kernel). Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"
Algoritmo di PCA locale overcomplete in ambiente GPU-CUDA L’algoritmo parallelo sviluppato, prevede una griglia computazionale 3D in cui ad ogni thread di un blocco è associato un voxel di competenza (i, j, z, k) in tutte le K direzioni dell’immagine DWI per un totale di k voxel per ogni thread. L’algoritmo parallelo sviluppato, prevede una griglia computazionale 3D in cui ad ogni thread di un blocco è associato un voxel di competenza (i, j, z, k) in tutte le K direzioni dell’immagine DWI. Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"
Algoritmo di PCA locale overcomplete in ambiente GPU-CUDA Versione 1 - full shared memory: uso totale di memoria condivisa in tutte le principali operazioni di PCA locale. KERNEL computeCovariance<<<-;-;->>> computePCA<<<-;-;->>> weightedAverage<<<-;-;->>> Versione 2 - shared and global memory combination: gestione oculata della shared memory in combinazione all’utilizzo della global memory. computeProdYEXW<<<-;-;->>> computeProdXDEYWT<<<-;-;->>> weightedAverage <<<-;-;->>> VANTAGGI SVANTAGGI Bassa latenza Risparmio maggiore di tempo Capienza ridotta Ho implementato due versione dell’algoritmo parallelo: Una prima versione chiamata full shared memory che fa un uso totale di memoria condivisa per tutte le operazioni di PCA. La shared memory ha il vantaggio di avere una bassa latenza ma al contempo stesso una capienza ridotta in termini di spazio. Per questo motivo ho realizzato una seconda versione che gestisce in maniera più oculata la memoria condivisa in combinazione con l’utilizzo della global memory che invece porta il vantaggio di avere una capienza maggiore al costo di tempi d’accesso più alti. La versione 1 utilizza solo 3 kernel mentre la seconda versione ne utilizza 4 di cui il primo e l’ultimo sono uguali alla prima versione. Vediamo ora, per grandi linee i kernel sviluppati! VANTAGGI SVANTAGGI Capienza maggiore Tempi d’accesso più alti Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"
computeCovariance<<<-;-;->>> versione 1-2 Questo kernel ha il compito di calcolare la matrice di covarianza C per ogni voxel (i, j, z). La configurazione di thread utilizzata è la seguente: BlockDim = GridDim = Vediamo ora i kernel sviluppati: Il kernel computeCovariance, comune ad entrambe le versioni, ha il compito di calcolare la matrice di covarianza C per ogni voxel (i, j, z). Ogni thread del blocco, in parallelo, copia i dati di propria competenza dall’immagine rumorosa alla shared memory per costruire la matrice X e poi esegue il prodotto righe per colonne per il calcolo della covarianza. Ogni thread del blocco, in parallelo, copia i dati di propria competenza dall’immagine rumorosa per costruire la matrice X in shared memory, poi calcola la media di ciascuna colonna della propria X (per normalizzare X) e per finire esegue il prodotto righe per colonne per il calcolo della matrice di covarianza C. Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"
computePCA<<<-;-;->>> versione 1 Calcola la Principal Component Analysis in maniera overcomplete usando la shared memory. La configurazione di griglia è la medesima del kernel precedente. Agisce in global memory sull’immagine di output per eseguire l’overlapping. Il kernel computePCA presente solo nella versione 1, calcola la PCA in maniera overcomplete utilizzando esclusivamente la shared memory. L’overlapping eseguito sempre in questo kernel, invece viene gestito nella global memory Nella fase di inizializzazione, i thread del blocco in parallelo costruiscono la matrice X, il vettore di media Mean e gli autovettori W in shared memory. Successivamente, eseguono tutte le operazioni di PCA locale e memorizzano i dati restaurati nell’immagine di output (overlapping). Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"
computeProdYEXW<<<-;-;->>> e computeProdXDEYWT<<<-;-;->>> versione 2 Nella versione 2, il kernel computePCA<<<-;-;->>> è splittato in due kernel che eseguono separatamente i prodotti per occupare meno spazio in shared memory. computeProdYEXW<<<-;-;->>> Ciascun thread di un blocco, in parallelo, prima effettua il prodotto tra matrici per generare Y, poi esegue il thresholding per la rimozione del rumore. Il prodotto fa un uso combinato di shared memory (X, W) e global memory (Y). computeProdXDEYWT<<<-;-;->>> Ciascun thread di un blocco, in parallelo, prima esegue il prodotto tra matrici per la determinazione della matrice XD restaurata, poi effettua overlapping per collocare i dati restaurati nell’immagine di output. Il prodotto fa un uso combinato di shared memory (MEAN, W) e global memory (Y, XD). Nella versione 2 il kernel computePCA è splittato in due kernel che eseguono separatamente i prodotti per occupare meno spazio in shared memory. Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"
weightedAverage<<<-;-;->>> versione 1-2 Calcola la media pesata per ogni voxel dell’immagine di output restaurata. La configurazione di griglia è la medesima dei kernel precedenti. Non fa uso di shared memory. Per finire, abbiamo il kernel weightedAverage, comune ad entrambe le versioni, che si occupa di calcolare la media pesata per ogni voxel dell’immagine di output restaurata. Non fa utilizzo di shared memory, ma agisce direttamente sulla global memory. Ogni thread di un blocco accede in memoria globale ai suoi K voxel di competenza ed esegue la media dividendo il valore del voxel (calcolato come somma delle stime di voxel dal processo di overlapping) per il numero di sovrapposizioni. Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"
Analisi di accuratezza dei risultati In questo primo test, si riportano i risultati numerici dell’errore di approssimazione commesso sulle immagine restaurate rispetto alle immagini originali (ground-truth). L’errore viene calcolato attraverso l’indice PSNR (Peak Signal-Noise Ratio) che è in grado di valutare la qualità delle immagini. Di seguito esaminiamo i risultati sperimentali per alcune immagini campione del dataset 3D, solo per alcune direzioni. Questo primo test è dedicato all’analisi di accuratezza dei risultati, calcolata numericamente attraverso l’errore di approssimazione commesso sulle immagini restaurate rispetto alle immagini ground-truth. L’indice utilizzato è il PSNR in grado di valutare la qualità delle immagini. ground-truth (z = 0, k = 0) ground-truth (z = 0, k = 5) ground-truth (z = 0, k = 9) Simulated DW-MRI Brain Data Sets: http://www.nitrc.org/projects/sim_dwi_brain/ Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"
Analisi di accuratezza dei risultati Si riportano i valori di PSNR per le tre immagini campione utilizzate, al variare del livello di rumore. Immagine K = 0 Livello Rumore Fattore Threshold Truth/Noise Truth/Denoise 3 % 3,5 39,3627 40,4992 5 % 4 35,1357 36,0129 7% 5,5 32,5834 33,3899 9 % 30,676 32,8739 Immagine K = 5 Livello Rumore Fattore Threshold Truth/Noise Truth/Denoise 3 % 3,5 40,0504 46,4654 5 % 4 36,5721 43,7716 7% 5,5 33,606 42,1731 9 % 31,471 40,4865 Qui di seguito sono riportati i dati numerici di PSNR che dimostrano che l’algoritmo è in grado di produrre risultati di output con un discreto grado di accuratezza. Immagine K = 9 Livello Rumore Fattore Threshold Truth/Noise Truth/Denoise 3 % 3,5 40,2151 46,8808 5 % 4 36,6531 44,0942 7% 5,5 33,7361 42,1145 9 % 31,5565 40,5904 Aumentando il livello di rumore, il PSNR tende a diminuire poichè l’immagine è più degradata. I valori (Truth/Denoise) sono più alti rispetto a (Truth/Noise) dato che l’immagine è restaurata ed ha una qualità maggiore. I valori tabellari dimostrano che l’algoritmo è in grado di produrre risultati di output con un discreto grado di accuratezza. Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"
Analisi di accuratezza dei risultati Risultati di output che si ottengono dall’esecuzione dell’algoritmo per un z fissato (z = 0), esaminando le direzioni k = 0, 5, 9 con i livelli di rumore 3% e 5%. LIVELLO RUMORE 3% LIVELLO RUMORE 5% In questa slide riportiamo invece alcuni risultati che mostrano il restauro da un punto di vista percettivo visivo per livelli di rumore pari a 3 e 5% Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"
Caratteristiche di esecuzione mediante profiling nvprof --print-gpu-trace ./myApp Lo strumento di profiling nvprof consente di raccogliere e visualizzare i dati relativi alle caratteristiche di esecuzione di un software parallelo eseguito su GPU in ambiente CUDA. Duration Grid size Block size DSMem Kernel Name 1.10s (88, 88, 7) (2, 2, 3) 8.48 KB computeCovariance 7.21s 34.40 KB computePCA 7.32ms 0 KB weightedAverage Output del tool, eseguendo la prima versione dell’algoritmo parallelo su 10 direzioni, con l’unica configurazione possibile di (2, 2, 3) thread per blocco e (88, 88, 7) blocchi. Output del tool, eseguendo la seconda versione dell’algoritmo parallelo su 10 direzioni, con la configurazione di (2, 2, 3) thread per blocco e (88, 88, 7) blocchi per un confronto diretto con la prima versione. Duration Grid size Block size DSMem Kernel Name 1.10s (88, 88, 7) (2, 2, 3) 8.48 KB computeCovariance 1.04s computeProdYEXW 5.42s computeProdXDEYWT 7.27ms 0 KB weightedAverage Lo strumento di profiling nvprof ci consente di visualizzare le caratteristiche di esecuzione del software parallello eseguito su GPU-CUDA. In questa slide sono riportati i risultati delle due versioni parallele su una stessa configurazione di thread ed utilizzando 10 direzioni. La differenza tra le due versioni parallele si apprezza nella quantità di shared memory sfruttata e nel numero di copie dati da host a device e viceversa. La differenza sostanziale tra le due versioni dell’algoritmo parallelo, sta nel numero di kernel utilizzati per ottenere il risultato, nella quantità di shared memory utilizzata e nel numero di copie dati da host a device e viceversa. Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"
Performance CPU vs GPU Sono stati effettuati vari test, variando per ogni esecuzione il numero di direzioni dell’immagine DWI (partendo da 2 direzioni ed arrivando fino a un massimo di 10 direzioni entro i limiti di memoria della macchina utilizzata). Dataset size (voxel) GFlops CPU GFlops GPU 1300992 0,03 0,33 1951488 0,05 0,63 2601984 0,13 1,6 3252480 0,31 3,8 3902976 0,7 8,16 4553472 1,41 17 5203968 2,6 31 5854464 4,3 51,51 6504960 7 83,14 Le performance dell’algoritmo sequenziale e parallelo sono state misurate in GFlops. Per 10 direzioni (massime sperimentali per motivi di spazio), si è ottenuto un guadagno prestazionale pari al 91,6% che giustifica a pieno l’utilizzo dell’architettura GPU per risolvere questo tipo di problema. Per 10 direzioni, le performance della CPU sono pari a 7 GFlops mentre per la GPU sono 83,14 GFlops, ovvero circa 12 volte maggiori rispetto a quelle della CPU ottenendo un guadagno prestazionale pari a 91,6%. Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"
Analisi dei tempi Nei diversi test, si è variato il numero di direzioni dell’immagine DWI (numero di voxel processati). Le due versioni parallele sono state eseguite con la stessa configurazione confrontabile (per motivi di spazio) di (2, 2, 3) thread per blocco e (88, 88, 7) blocchi di griglia. Dataset size (voxel) Time CPU Time GPU v1 Time GPU v2 1300992 17 1,04 1,35 1951488 25 1,72 2,03 2601984 31 2,82 3,1 3252480 39 4,23 4,61 3902976 49 6,6 6,7 4553472 57 9,1 9,74 5203968 68 15,01 12,8 5854464 82 18,4 17,4 6504960 95 23,55 24 Il software parallelo eseguito su GPU, produce risultati di output con tempi d’esecuzione all’incirca 4 volte minori rispetto all’algoritmo sequenziale eseguito su CPU con un guadagno pari al 75%. CONSIDERAZIONI SU EVENTUALI DOMANDE Se in termini di tempo, le due versioni hanno tempi approssimativamente uguali, qual è la migliore? Se confrontiamo le due versioni esclusivamente sul tempo impiegato e per le direzioni che ho avuto modo di sperimentare, la differenza apprezzabile è così piccola da non poter dire quale delle due sia la migliore perchè quasi si equivalgono. Però, con una quantità di dati molto maggiore, la bassa latenza della shared memory potrebbe portare ad avere tempi d’esecuzione molto più ridotti della versione 2 (ci vorrebbe però una shared memory molto più capiente). Quindi, almeno per questo tipo di problema il vantaggio ottenuto utilizzando le GPU in fase di calcolo (per entrambe le versioni) è così elevato che utilizzare o meno la shared memory non migliora più di tanto la situazione. Se invece consideriamo la differenza in termini di spazio, è chiaro che la versione migliore è senza dubbio la versione 2 perchè con quasi gli stessi tempi è in grado di poter elaborare una quantità di dati maggiore con la possibilità di poter variare anche le dimensioni della griglia computazionale. Cosa che invece non è possibile fare con la versione 1, perchè non ho la possibilità di allocare abbastanza spazio sulla shared memory. Con 10 direzioni, il tempo impiegato dalla CPU è di 95 secondi contro i 24 secondi della GPU (i tempi delle due versioni sono approssimativamente uguali). Pertanto, il tempo impiegato dalla GPU è circa 4 volte minore rispetto al tempo impiegato dalla CPU, con un guadagno pari al 75%. Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"
Tempi d’esecuzione algoritmo parallelo (ver. 2) L’algoritmo parallelo è stato eseguito al variare delle direzioni, processando i voxel dell’immagine con diverse configurazioni di griglia, nei limiti dello spazio a disposizione sulla macchina utilizzata. Thread per blocco Direzioni Time GPU v2 Time GPU v1 2 x 2 x 3 2 1,35 1,04 3 x 3 x 3 1,43 1,1 4 x 4 x 3 1,45 5 x 5 x 3 1,5 1,27 10 24 23,55 31,8 - 35,6 29,30 In questo esperimento sono stati rilevati i tempi d’esecuzione delle versioni 2 dell’algoritmo parallelo al variare delle direzioni e delle configurazioni di griglia. Aumentando il numero di direzioni il carico di lavoro e quindi anche il tempo necessario aumenta a prescindere dalla configurazione utilizzata anche se la configurazione ottimale è sempre quella che utilizza 2x2x3 thread per blocco. Per completezza ho aggiunto in tabella anche i tempi della versione 1, ma si può notare che non è possibile utilizzare una configurazioone differente all’aumentare delle direzioni perchè non ho la possibilità di allocare abbastanza spazio sulla shared memory. Aumentando le direzioni, il carico di lavoro aumenta a prescindere dalla configurazione utilizzata. Per ogni direzione, la configurazione ottimale è sempre quella che utilizza 2 x 2 x 3 thread per blocco. Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"
Conclusioni e Sviluppi Futuri Con il lavoro svolto in questa tesi, si è realizzata una implementazione parallela del metodo “PCA Locale Overcomplete (OLPCA)” per la rimozione del rumore Rician da immagini pesate in diffusione, in ambiente GPU-CUDA. Sono state sviluppate due versioni parallele, per sopperire alle limitazioni dell’architettura utilizzata. I risultati sperimentali, di confronto con l’algoritmo sequenziale, hanno evidenziato un guadagno in termini di GFlops addirittura pari al 91,6% ed una riduzione del tempo di esecuzione uguale al 75%. SVILUPPI FUTURI Con il lavoro svolto in questa tesi, ho realizzato una implementazione parallela del metodo OLPCA. Nello specifico, ho sviluppato due versioni parallele, per sopperire alle limitazioni dell’architettura utilizzata e per effettuare un confronto di prestazioni tra le due memorie (shared e global memory). I risultati sperimentali hanno evidenziato un notevole guadagno sia in termini di prestazioni che in termini di riduzione del tempo d’esecuzione dell’algoritmo parallelo rispetto alla versione sequenziale. L’algoritmo parallelo può senza ombra di dubbio essere migliorato... Ad esempio si potrebbe pensare ad una implementazione multi-GPU per incrementare ulteriormente il guadagno e aumentare lo spazio a disposizione. Infine, sarebbe interessante testare il software parallelo su schede video con memorie più capienti. Implementazione multi-GPU per incrementare ulteriormente il guadagno. Testing del software parallelo su schede video con memorie più capienti. Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"
Grazie a tutti per l’attenzione!
Analisi supplementari
Tempi d’esecuzione a confronto tra le due versioni Thread per blocco Time GPU v1 Time GPU v2 2 x 2 x 3 1,04 1,35 3 x 3 x 3 1,1 1,43 4 x 4 x 3 1,45 5 x 5 x 3 1,27 1,5 Qui di seguito confrontiamo i tempi d’esecuzione tra le due versioni, variando il numero di configurazioni di thread ma mantenendo fissato il numero di direzioni a 2 per mancanza di spazio nella shared memory. Possiamo ancora una volta ribadire che la differenza nei tempi d’esecuzione è decisamente bassa ed è senz’altro dovuta al tempo di accesso alla global memory ed alla quantità maggiore di trasferimenti dati in memoria. Anche questo test conferma che la configurazione ottimale è quella che prevede 2x2x3 thread per blocco. La differenza nei tempi d’esecuzione tra le due versioni è decisamente bassa. I tempi della seconda versione parallela, sono influenzati dalla quantità maggiore di trasferimenti dati in memoria e dall’accesso alla global memory. I risultati confermano ancora una volta che la configurazione ottimale è certamente quella che prevede l’uso di blocchi da 2 x 2 x 3 thread. Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"
Tempi d’esecuzione per il calcolo degli autovettori W L’algoritmo è stato eseguito al variare delle direzioni, rilevando per ogni test il tempo di esecuzione necessario alla computazione degli autovettori su host. Dataset size (voxel) Direzioni Time W 1300992 2 0,9 1951488 3 1,31 2601984 4 3252480 5 3,1 3902976 6 4,45 4553472 7 6,4 5203968 8 8,25 5854464 9 11,30 6504960 10 15 In questo test è mostrato il tempo di esecuzione necessario alla computazione degli autovettori che è una parte di calcolo del PCA che non è stata parallelizzata e rappresenta un collo di bottiglia per l’algoritmo parallelo. La curva dei tempi assume un andamento quadratico che incide sul tempo globale dell’algoritmo parallelo. Il tempo d’esecuzione aumenta all’aumentare delle direzioni dell’immagine DWI con un andamento quadratico! Ivan Osato - Università degli Studi di Napoli "Parthenope" Ivan Osato - Università degli Studi di Napoli "Parthenope"