Compute Unified Device Architecture

Un article de Wikipédia, l'encyclopédie libre.
(Redirigé depuis CUDA)
Aller à : navigation, rechercher
Schéma de principe de l'architecture CUDA

CUDA (Compute Unified Device Architecture) est une technologie de GPGPU (General-Purpose Computing on Graphics Processing Units), c'est-à-dire qu'un processeur graphique (GPU) est utilisé pour exécuter des calculs généraux habituellement exécutés par le processeur central (CPU). CUDA permet de programmer des GPU en C. Cette technologie a été développée par Nvidia pour leurs cartes graphiques GeForce 8 Series, et utilise un pilote unifié utilisant une technique de streaming (flux continu). Le premier kit de développement pour CUDA a été publié le 15 février 2007[1].

Utilisations de CUDA[modifier | modifier le code]

Architecture Tesla[modifier | modifier le code]

L'architecture Tesla, qui offre selon NVidia la puissance de calcul d'un superordinateur (4 téraflops en simple précision, 80 gigaflops en double précision) pour une somme de 10 000 dollars, est construite sur CUDA.

Programmation[modifier | modifier le code]

CUDA présente plusieurs particularités par rapport à la programmation en C en proposant d'effectuer des calculs génériques sur GPU :

  • Hierachisation mémoire explicite (privé, locale, globale) permettant d'organiser finement les transferts mémoires
  • Regroupement des threads en grilles de grilles : grille 1D,2D ou 3D locale de threads pouvant partager rapidement la mémoire locale. Les grilles locales sont ordonnées en grille globale permettant d'accéder à la mémoire globale

Avantage[modifier | modifier le code]

  • Accès relativement standardisé à la puissance de calcul.

Limitations[modifier | modifier le code]

  • Les transferts entre le host et le device peuvent être un goulot d'étranglement (peut être évité par des copies asynchrones).
  • Regroupement des threads en groupe de 32 pour des questions de performances (les warps). Au sein d'un warp, les divergences (dues aux exécutions conditionnelles) peuvent nuire grandement aux performances. Il s'agit d'une limitation due au modèle SIMD. De ce fait, tous les algorithmes ne gagnent pas à être portés sur CUDA, et plus généralement sur un modèle SIMD.
  • Un code C valide peut être rejeté à cause des contraintes matérielles (manque de mémoire, nombre de threads).
  • Les premières versions (1.x) de CUDA ne supportent pas la récursion, les pointeurs de fonctions, et d'autres limitations qui tendent à disparaître.
  • La précision des calculs. La double-précision n'est disponible que depuis la version 1.3 ; et la norme IEEE 754 n'est que partiellement atteinte : en double précision, le seul mode d'arrondi est round-to-nearest-even. En simple précision, les nombres ne sont pas dénormalisés, le signal NaN est absent, et les 2 seuls modes d'arrondi sont chop and round-to-nearest even, etc.

Exemples[modifier | modifier le code]

Exemple avec émulation de carte[modifier | modifier le code]

#include <stdio.h>
#include <stdlib.h>
#include <cuda.h>
#include <cuda_runtime.h>
 
 
__global__ void mykernel(float * A1, float * A2, float * R)
{
	int p = threadIdx.x;
	R[p] = A1[p] + A2[p];
}
 
int main()
{
	float A1[]={1,2,3,4,5,6,7,8,9};
	float A2[]={10,20,30,40,50,60,70,80,90};
	float R[9];
 
	//9 additions, aucune boucle !
	mykernel<<<1,9>>>(A1,A2,R);
 
	//sortie à l'ecran
	for(int i=0; i<9 ; i++)
		printf("%f\n",R[i]);
 
}

Cet exemple fonctionne seulement si on émule la carte graphique car on ne recopie pas les données sur la carte.

Compilation par :

nvcc -deviceemu -o run prog.cu

Exemple avec une carte graphique NVidia[modifier | modifier le code]

#include <stdio.h>
#include <stdlib.h>
#include <cuda.h>
#include <cuda_runtime.h>
 
 
__global__ void mykernel(float * A1, float * A2, float * R)
{
        int p = threadIdx.x;
        R[p] = A1[p] + A2[p];
}
 
int main()
{
        float A1[]={1,2,3,4,5,6,7,8,9};
        float A2[]={10,20,30,40,50,60,70,80,90};
        float R[9];
        int taille_mem=sizeof(float) * 9;
        // on alloue de la memoire sur la carte graphique
        float * a1_device;
        float * a2_device;
        float * r_device;
        cudaMalloc ( (void**) &a1_device, taille_mem);
        cudaMalloc ( (void**) &a2_device, taille_mem);
        cudaMalloc ( (void**) &r_device, taille_mem);
        // on copie les donnees sur la carte
        cudaMemcpy( a1_device,A1,taille_mem,cudaMemcpyHostToDevice);
        cudaMemcpy( a2_device,A2,taille_mem,cudaMemcpyHostToDevice);
 
        //9 additions, aucune boucle !
        mykernel<<<1,9>>>(a1_device,a2_device,r_device);
 
        // on recupere le resultat
        cudaMemcpy(R,r_device,taille_mem,cudaMemcpyDeviceToHost);
        //sortie à l'ecran
        for(int i=0; i<9 ; i++)
                printf("%f\n",R[i]);
 
}

Compilation par :

nvcc -o add_cuda add_cuda.cu

Voir aussi[modifier | modifier le code]

Installation de CUDA en fonction des systèmes d'exploitation[modifier | modifier le code]

Produits concurrents[modifier | modifier le code]

Références[modifier | modifier le code]

  1. (en) http://news.developer.nvidia.com/2007/02/cuda_for_gpu_co.html

Articles connexes[modifier | modifier le code]

Liens externes[modifier | modifier le code]