CUDA

linguaggio di programmazione

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 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
software
GenereGPGPU (non in lista)
SviluppatoreNVIDIA Corporation
Data prima versione23 giugno 2007; 16 anni fa
Ultima versione11.3.0 (15 aprile 2021; 2 anni fa)
Sistema operativoWindows 10
Licenzafreeware
(licenza non libera)
Sito webNvidia's CUDA zone

CUDA dà accesso agli sviluppatori ad un set di istruzioni native per il calcolo parallelo di elementi delle GPU CUDA. Usando CUDA, le ultime GPU Nvidia diventano in effetti 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 questo tipo di architettura, la GPU può offrire grandi prestazioni e benefici. Questo approccio alla risoluzione dei problemi è noto come GPGPU.

Vantaggi modifica

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

  • Il codice può essere letto da posizioni arbitrarie in memoria.
  • Memoria condivisa: CUDA espone una regione di 16kB di grandezza che può essere condivisa velocemente fra i thread. Questa può essere usata come una cache gestita dall'utente, rendendo disponibili grandi larghezze di banda che è possibile usare per strutture texture.
  • Letture e scritture veloci, verso e dalla GPU.
  • Supporto completo per divisioni intere e operazioni bit-a-bit, tra cui l'accesso a texture intere.

Limitazioni modifica

  • CUDA era inizialmente un sottoinsieme del linguaggio C, privo di ricorsione e puntatori a funzione, più alcune semplici estensioni. Un singolo processo deve essere eseguito attraverso multiple disgiunzioni di spazi di memoria, diversamente da altri ambienti di runtime C. Le versioni più recenti tuttavia usano la sintassi C++. Il codice scritto per le versioni precedenti può non compilare, oppure può comportarsi in modo differente.
  • Il rendering delle texture non è supportato.
  • Per la doppia precisione, supportata a partire dalla serie GTX 2XX, 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 NAN segnalati e denormalizzati non sono supportati; queste sono specifiche per istruzioni di base, rispetto ad una singola parola di controllo[non chiaro]; 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 devono 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, per esempio 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)
  • La gestione delle eccezioni non è supportata nel codice CUDA a causa del degrado delle prestazioni risultante con migliaia di thread in esecuzione.
  • Nelle versioni più recenti non esistono emulatori software per l'esecuzione del codice CUDA.

Lista GPU supportate modifica

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

Nvidia GeForce
Geforce GTX 10xx
GeForce GTX 9xx
GeForce GTX 7xx
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 GTX 880M
GeForce GTX 870M
GeForce GTX 860M
GeForce GTX 780M
GeForce GTX 770M
GeForce GTX 765M
GeForce GTX 760M
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

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.

I progetti BOINC supportati dalla piattaforma Nvidia CUDA sono:[1]

  • Collatz Conjecture: si pone come obiettivo la soluzione della celebre congettura di Collatz (o 3n + 1)
  • DistrRTgen: è un progetto volto alla creazione di rainbow table distribuite gratuitamente
  • Einstein@home: ha lo scopo di analizzare i dati prodotti da osservatori astronomici per rilevare delle onde gravitazionali da diverse fonti, come ad esempio i buchi neri
  • GPUgrid.net: è un progetto nel campo della ricerca biomedica
  • Milkyway@home: l'obiettivo di questo progetto è la creazione di un accurato modello tridimensionale della Via Lattea, utilizzando i dati forniti dallo Sloan Digital Sky Survey
  • Moo!: permette di partecipare alla competizione RC5-72, è un wrapper di distributed.net
  • PrimeGrid: esegue la ricerca dei numeri primi più elevati al mondo
  • SETI@home: è il famosissimo progetto di calcolo distribuito, utilizza i dati del radiotelescopio di Arecibo per la ricerca di segnali correlati a intelligenze extraterrestri

Esempi modifica

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()

Note modifica

  1. ^ GPU computing - BOINC, su boinc.berkeley.edu. URL consultato il 7 febbraio 2016.

Voci correlate modifica

Altri progetti modifica

Collegamenti esterni modifica

Controllo di autoritàLCCN (ENsh2013001284 · GND (DE7719528-0 · J9U (ENHE987007568350905171