CUDA

Da Wikipedia, l'enciclopedia libera.
CUDA
Sviluppatore NVIDIA Corporation
Ultima Release Stabile 5
OS Windows 8, Windows 7, Windows Vista, Windows XP, Windows Server 2008, Windows Server 2003, Linux, Mac OS X
Genere GPGPU
Licenza Proprietario, Freeware
Sito Nvidia's CUDA

CUDA (acronimo di Compute Unified Device Architecture) è un'architettura hardware per l'elaborazione parallela creata da NVIDIA. Tramite l'ambiente di sviluppo per CUDA, i programmatori di software possono scrivere applicazioni capaci di eseguire calcolo parallelo sulle GPU delle schede video NVIDIA.
I linguaggi di programmazione disponibili nell'ambiente di sviluppo per CUDA, sono estensioni dei linguaggi più diffusi per scrivere programmi. Il principale è 'CUDA-C' (C con estensioni NVIDIA), altri sono estensioni di Python, Fortran, Java e MATLAB.
Programmi che sfruttano l'architettura CUDA possono essere scritti anche utilizzando le librerie software OpenCL e DirectCompute.

CUDA dà accesso agli sviluppatori ad un set di istruzioni native per la computazione parallela di elementi delle GPU CUDA. Usando CUDA, le ultime GPU Nvidia effettivamente diventano architetture aperte come le CPU. Diversamente dalle CPU, le GPU hanno un'architettura parallela con diversi core, ognuno capace di eseguire centinaia di processi simultaneamente - se un'applicazione è adatta per quel tipo di architettura, la GPU può offrire grandi performance e benefici. Questo approccio di risoluzione dei problemi è noto come GPGPU.

Vantaggi[modifica | modifica sorgente]

CUDA ha parecchi vantaggi rispetto alle tradizionali tecniche di computazione sulle GPU che usano le API grafiche.

  • Letture temporali - il codice può essere letto attraverso indirizzi arbitrari di memoria.
  • Memoria condivisa - CUDA espone una veloce condivisione di memoria (una regione di 16kb di grandezza) che può essere condivisa fra i thread. Questa può essere usata come una cache gestita da utenti, abilitando grandi larghezze di banda che è possibile usare per strutture texture.
  • Veloci downloads e riletture verso e dalla GPU.
  • Supporto completo per divisioni intere e operazioni bit-a-bit, incluse strutture texture intere.

Limitazioni[modifica | modifica sorgente]

  • CUDA è un sottoinsieme del linguaggio C privo di ricorsione e puntatori a funzione, più alcune semplici estensioni. Comunque, un singolo processo deve essere eseguito attraverso multiple disgiunzioni di spazi di memoria, diversamente da altri ambienti di runtime C.
  • Il rendering delle texture non è supportato.
  • Per la doppia precisione (supportata nelle nuove GPU come la GTX 260) ci sono diverse deviazioni dallo standard IEEE 754: l'arrotondamento al pari è l'unica approssimazione supportata per: reciproci, divisioni e radici quadrate. In singola precisione, i NANs segnalati e denormalizzati non sono supportati; queste sono specifiche per istruzioni di base, rispetto ad una singola parola di controllo; e la precisione delle cifre decimali di divisioni o radici n-esime è molto minore rispetto alla singola precisione.
  • La larghezza di banda e la latenza tra CPU e GPU può essere un collo di bottiglia.
  • I thread devo essere eseguiti in multipli di 32 per ottenere migliori prestazioni, con un numero totale di thread nell'ordine di migliaia. I rami dei codici non influiscono nelle prestazioni, a condizione che ciascuno dei 32 thread prenda lo stesso cammino di esecuzione. Il modello di esecuzione SIMD diviene una limitazione significativa per diversi compiti (e.x. l'attraversamento di uno spazio partizionato di strutture dati durante il raytracing).
  • Diversamente da OpenCL, GPU dotate di CUDA sono disponibili solo da NVIDIA (GeForce 8 serie superiori, Quadro e Tesla)

Lista Gpu supportate[modifica | modifica sorgente]

Ecco una lista hardware che supporta ufficialmente CUDA (Notare che molte applicazioni richiedono almeno 256 MB di VRAM dedicata)

Nvidia GeForce
GeForce GT\GTX 6xx
GeForce GTX 580
GeForce GTX 570
GeForce GTX 560 Ti
GeForce GTX 480
GeForce GTX 470
GeForce GTX 465
GeForce GTX 460
GeForce GT 430
GeForce GTX 295
GeForce GTX 285
GeForce GTX 280
GeForce GTX 275
GeForce GTX 260
GeForce GTS 250
GeForce GTS 240
GeForce GT 240
GeForce GT 220
GeForce GT 330M
GeForce 210/G210
GeForce 9800 GX2
GeForce 9800 GTX+
GeForce 9800 GTX
GeForce 9800 GT
GeForce 9600 GSO
GeForce 9600 GT
GeForce 9500 GT
GeForce 9400 GT
GeForce 9400 mGPU
GeForce 9300 mGPU
GeForce 9100 mGPU
GeForce 8800 Ultra
GeForce 8800 GTX
GeForce 8800 GTS
GeForce 8800 GT
GeForce 8800 GS
GeForce 8600 GTS
GeForce 8600 GT
GeForce 8600 mGT
GeForce 8500 GT
GeForce 8400 GS
GeForce 8300 mGPU
GeForce 8200 mGPU
GeForce 8100 mGPU
Nvidia GeForce Mobile
GeForce GT\GTX 6xx
GeForce GT\GTX 5xx
GeForce GT\GTX 4xx
GeForce GT\GTX 3xx
GeForce GTX 285M
GeForce GTX 280M
GeForce GTX 260M
GeForce GTS 260M
GeForce GTS 250M
GeForce GT 240M
GeForce GT 230M
GeForce GT 220M
GeForce G210M
GeForce GTS 160M
GeForce GTS 150M
GeForce GT 130M
GeForce GT 120M
GeForce G110M
GeForce G105M
GeForce G102M
GeForce G100
GeForce 9800M GTX
GeForce 9800M GTS
GeForce 9800M GT
GeForce 9800M GS
GeForce 9700M GTS
GeForce 9700M GT
GeForce 9650M GT
GeForce 9650M GS
GeForce 9600M GT
GeForce 9600M GS
GeForce 9500M GS
GeForce 9500M G
GeForce 9400M G
GeForce 9300M GS
GeForce 9300M G
GeForce 9200M GS
GeForce 9100M G
GeForce 8800M GTX
GeForce 8800M GTS
GeForce 8700M GT
GeForce 8600M GT
GeForce 8600M GS
GeForce 8400M GT
GeForce 8400M GS
GeForce 8400M G
GeForce 8200M G
Nvidia Quadro
Quadro FX 5800
Quadro FX 5600
Quadro FX 4800
Quadro FX 4700 X2
Quadro FX 4600
Quadro FX 3800
Quadro FX 3700
Quadro FX 1800
Quadro FX 1700
Quadro FX 580
Quadro FX 570
Quadro FX 380
Quadro FX 370
Quadro NVS 450
Quadro NVS 420
Quadro NVS 295
Quadro NVS 290
Quadro Plex 1000 Model IV
Quadro Plex 1000 Model S4
Nvidia Quadro Mobile
Quadro FX 3700M
Quadro FX 3600M
Quadro FX 2700M
Quadro FX 1700M
Quadro FX 1600M
Quadro FX 770M
Quadro FX 570M
Quadro FX 370M
Quadro FX 360M
Quadro NVS 320M
Quadro NVS 160M
Quadro NVS 150M
Quadro NVS 140M
Quadro NVS 135M
Quadro NVS 130M
Nvidia Tesla
Tesla S1070
Tesla C1060
Tesla C870
Tesla D870
Tesla S870
Nvidia ION
ION
Next Generation-ION

CUDA Nvidia e BOINC[modifica | modifica sorgente]

La piattaforma Boinc (Berkeley Open Infrastructure for Network Computing) ha diversi progetti di calcolo distribuito che supportano e sfruttano a pieno le potenzialità e i benefici della tecnologia CUDA. Un esempio è PrimeGrid, un progetto di ricerca di matematica sui numeri primi; degno di nota è anche GPUGrid, incentrato sullo studio della dinamica molecolare per la lotta a molte malattie.

Esempi[modifica | modifica sorgente]

Questo esempio di codice in C++ carica una texture da un'immagine dentro un array della GPU:

*cudaArray* cu_array;
texture<float, 2> tex;
 
// Allocate array
cudaChannelFormatDesc description = cudaCreateChannelDesc<float>();
cudaMallocArray(&cu_array, &description, width, height);
 
// Copy image data to array
cudaMemcpy(cu_array, image, width*height*sizeof(float), cudaMemcpyHostToDevice);
 
// Bind the array to the texture
cudaBindTextureToArray(tex, cu_array);
 
// Run kernel
dim3 blockDim(16, 16, 1);
dim3 gridDim(width / blockDim.x, height / blockDim.y, 1);
kernel<<< gridDim, blockDim, 0 >>>(d_odata, height, width);
cudaUnbindTexture(tex);
 
__global__ void kernel(float* odata, int height, int width)
{
   unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
   unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
   float c = tex2D(tex, x, y);
   odata[y*width+x] = c;
}

Sotto un esempio in Python che computa il prodotto di due array nella GPU. Il linguaggio non ufficiale Python può essere ottenuto da PyCUDA.

import pycuda.driver as drv
import numpy
import pycuda.autoinit
 
mod = drv.SourceModule("""
__global__ void multiply_them(float *dest, float *a, float *b)
{
  const int i = threadIdx.x;
  dest[i] = a[i] * b[i];
}
""")
 
multiply_them = mod.get_function("multiply_them")
 
a = numpy.random.randn(400).astype(numpy.float32)
b = numpy.random.randn(400).astype(numpy.float32)
 
dest = numpy.zeros_like(a)
multiply_them(
        drv.Out(dest), drv.In(a), drv.In(b),
        block=(400,1,1))
 
print dest-a*b

Altri Python bindings per semplificare i prodotti tra matrici possono essere trovati su pycublas.

import numpy
from pycublas import CUBLASMatrix
A = CUBLASMatrix( numpy.mat([[1,2,3],[4,5,6]],numpy.float32) )
B = CUBLASMatrix( numpy.mat([[2,3],[4,5],[6,7]],numpy.float32) )
C = A*B
print C.np_mat()

Voci correlate[modifica | modifica sorgente]

Collegamenti esterni[modifica | modifica sorgente]