CUDA

Uit Wikipedia, de vrije encyclopedie
Ga naar: navigatie, zoeken
CUDA
Ontwikkelaar NVIDIA
Recentste versie 5.0 
(15 oktober 2012)
Status Uitgebracht
Besturingssysteem Windows XP+, Windows Server 2003+, Linux en Mac OS X
Categorie GPGPU
Licentie Propriëtaire freeware
Website (en) Nvidia's CUDA zone Officiële website
Portaal  Portaalicoon   Informatica

CUDA, wat staat voor Compute Unified Device Architecture, is een GPGPU-technologie die het de programmeur mogelijk maakt om gebruik te maken van de programmeertaal C om algoritmes uit te voeren op de GPU.

Verloop van een verwerking met CUDA
1. Kopieer data van main mem naar GPU mem
2. CPU geeft instructies voor het proces op de GPU
3. GPU voert parallel uit in elke core
4. Kopieer het resultaat van GPU mem naar main mem

CUDA is ontwikkeld door NVIDIA en om gebruik te maken van deze computerarchitectuur is er een NVIDIA GPU en een speciale stream processing driver vereist. CUDA werkt alleen op de nieuwere grafische kaarten GeForce 8 serie, die gebruikmaken van de G8x GPUs; NVIDIA garandeert dat programma's ontwikkeld voor de GeForce 8-serie zonder enige aanpassing zullen werken op alle toekomstige NVIDIA grafische kaarten. CUDA geeft ontwikkelaars toegang tot de native instruction-set en geheugen van de omvangrijke parallelle computer elementen in CUDA GPUs. Gebruikmakend van CUDA worden de NVIDIA GeForce gebaseerde GPUs effectief krachtige, programmeerbare open architecturen, zoals hedendaagse CPU's.

Voor- en nadelen[bewerken]

CUDA heeft enkele voor- en nadelen ten opzichte van traditionele 'general-purpose computation' op GPU's (GPGPU) door gebruik van API's.

Voordelen:

  • Maakt gebruik van standaard C, met enkele simpele extensies;
  • Scattered writes - code kan naar willekeurige adressen in het geheugen schrijven;
  • Shared memory;
  • Snellere downloads en readbacks van en naar de GPU;
  • Volledige ondersteuning voor integer en bit-wise bewerkingen.

Nadelen:

  • Ondersteunt alleen bilinear texture filtering - mipmapped textures en anisotropic filtering worden heden nog niet ondersteund;
  • Recursieve functies worden niet ondersteund;
  • Enkele afwijkingen ten opzichte van IEEE 754 standaard. Denormals en signalling NaNs worden niet ondersteund, alleen twee afrondingsmethodes worden ondersteund (chop en round-to-nearest even);
  • CUDA-enabled GPU's worden alleen door NVIDIA gemaakt (GeForce, Quadro, Tesla).

Ondersteuning[bewerken]

Een tabel van apparaten welke officieel ondersteuning van CUDA hebben (Veel applicaties vereisen minstens 256 MB VRAM).[1]

Nvidia GeForce
GeForce GTX TITAN-Z
GeForce GTX TITAN BLACK
GeForce GTX TITAN
GeForce GTX 980
GeForce GTX 970
GeForce GTX 780 Ti
GeForce GTX 780
GeForce GTX 770
GeForce GTX 750
GeForce GTX 760
GeForce GTX 690
GeForce GTX 680
GeForce GTX 680M
GeForce GTX 670
GeForce GTX 660
GeForce GTX 660 Ti
GeForce GTX 660
GeForce GTX 660M
GeForce GTX 650 Ti
GeForce GTX 650
GeForce GTX 650M
GeForce GT 640
GeForce GTX 640M
GeForce GTX 590
GeForce GTX 580
GeForce GTX 570
GeForce GTX 555
GeForce GTX 480
GeForce GTX 470
GeForce GTX 465
GeForce GTX 460
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 230
GeForce GT 220
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 285M
GeForce GTX 280M
GeForce GTX 260M
GeForce GTS 360M
GeForce GTS 350M
GeForce GTS 260M
GeForce GTS 250M
GeForce GT 555M
GeForce GT 540M
GeForce GT 335M
GeForce GT 330M
GeForce GT 325M
GeForce GT 320M
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 G103M
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 3800M
Quadro FX 3700M
Quadro FX 3600M
Quadro FX 2800M
Quadro FX 2700M
Quadro FX 1800M
Quadro FX 1700M
Quadro FX 1600M
Quadro FX 880M
Quadro FX 770M
Quadro FX 570M
Quadro FX 380M
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 M1060
Tesla C1060
Tesla C870
Tesla D870
Tesla S870

Voorbeeld[bewerken]

Deze voorbeeldcode in C++ laadt een texture van een afbeelding in een array op de GPU:

cudaArray* cu_array;
texture<float, 2> tex;
 
// Alloceert array
cudaChannelFormatDesc description = cudaCreateChannelDesc<float>();
cudaMallocArray(&cu_array, &description, width, height);
 
// Kopieert afbeelding data naar array
cudaMemcpy(cu_array, image, width*height*sizeof(float), cudaMemcpyHostToDevice);
 
// Bindt de array naar de texture
cudaBindTextureToArray(tex, cu_array);
 
// Start 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;
}

Hieronder is een voorbeeld in Python die het product berekent van twee arrays op de GPU. De onofficiële Python bindings kan worden verkregen van 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

Aanvullende Python bindings om matrixvermenigvuldiging te vereenvoudigen kunnen worden gevonden in het programma 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()

Programmeerhulpmiddelen[bewerken]

Fermi[bewerken]

De volgende generatie CUDA-architecturen (codenaam: "Fermi") welke standaard zijn op NVIDIA's aankomende (GeForce 400 Series [GF100] (GPU) uitgebracht 27-03-2010)[2] GPU die vanaf het begin ontworpen is om ondersteuning te bieden voor meer programmeertalen zoals C++. Er wordt verwacht om acht keer de piek double-precision floating-point prestaties te hebben in vergelijking met Nvidia's vorige-generatie Tesla GPU. Het introduceert ook een aantal nieuwe functies[3] zoals:

  • tot 512 CUDA cores en 3.0 miljard transistors
  • NVIDIA Parallel DataCache technology
  • NVIDIA GigaThread engine
  • ECC memory ondersteuning
  • Gedegen ondersteuning voor Visual Studio

Zie ook[bewerken]

Externe link[bewerken]

Bronnen, noten en/of referenties