CUDA

CUDA
Ontwikkelaar(s) NVIDIA
Uitgebracht 23 juni 2007
(17 jaar)
Recentste versie 12.1 (1 maart 2023),[1][2] 12.2 (28 juni 2023),[3] 12.3.1 (15 november 2023),[4] 12.5.1 (juli 2024),[5] 12.6.1 (augustus 2024)[6] Bewerken op Wikidata
Status Actief
Besturingssysteem Windows, Linux, macOS
Categorie GPGPU
Licentie(s) Propriëtaire freeware
Website (mul) 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 GPU's; 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 computerelementen in CUDA GPU-s. Gebruikmakend van CUDA worden de NVIDIA GeForce-gebaseerde GPU's effectief krachtige, programmeerbare open architecturen, zoals hedendaagse CPU's.

Voor- en nadelen

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 NaN's 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

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

Nvidia GeForce
GeForce GTX TITAN-Z
GeForce GTX TITAN-X
GeForce GTX TITAN BLACK
GeForce GTX TITAN
GeForce GTX 1080 Ti
GeForce GTX 1080
GeForce GTX 1070 Ti
GeForce GTX 1070
GeForce GTX 1060 (6GB)
GeForce GTX 1060 (3GB)
GeForce GTX 1050 Ti
GeForce GTX 1050
GeForce GTX 980 Ti
GeForce GTX 980
GeForce GTX 970
GeForce GTX 960
GeForce GTX 950
GeForce GTX 780 Ti
GeForce GTX 780
GeForce GTX 770
GeForce GTX 750
GeForce GTX 760 (OEM)
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 840M
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

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 kunnen 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

Generaties GPU's

Fermi

De generatie GPU's met de codenaam Fermi (uitgebracht 27 maart 2010, GeForce 400 Series [GF100])[8] werd vanaf het begin ontworpen om ondersteuning te bieden voor meer programmeertalen zoals C++. Er wordt verwacht om acht keer de piek double-precision floating-point prestaties te bereiken in vergelijking met Nvidia's vorige-generatie Tesla-GPU. Het introduceert ook een aantal nieuwe functies[9] zoals:

  • Tot 512 CUDA-cores en 3 miljard transistors
  • NVIDIA Parallel DataCache
  • NVIDIA GigaThread engine
  • Ondersteuning voor ECC-geheugen
  • Gedegen ondersteuning voor Microsoft Visual Studio

Kepler

Kepler (2016) ondersteunt eveneens CUDA.[10]

Volta

Volta is anno 2018 de meest recente generatie van grafische kaarten. Deze ondersteunt ook CUDA.

Zie ook