CUDA

5      Programmation avec CUDA

D’un point de vue programmation, CUDA est un langage dérivé du C. Il n’y apporte que peu de modifications : 9 nouveaux mots clés, 24 types et 62 fonctions spécifiques à l’API, ainsi qu’une syntaxe pour le code à paralléliser.

Pour programmer l’exécution de code sur un GPU avec CUDA, il faut définir le bout de code à exécuter (qui sera exécuté en une multitude de threads), qui sera appelé par le thread principal du CPU.
Ce bout de code exécuté sur le GPU consiste en une fonction, appelée « kernel« , respectant certaines contraintes : syntaxe, spécification du nombre de threads exécutant le kernel, la quantité de mémoire partagée, etc.

5.1 Kernel CUDA

Un kernel CUDA est une fonction soumise aux contraintes suivantes :

  • Identificateur précédent la déclaration de la fonction :
    • __device__ pour un kernel appelable uniquement depuis le GPU
    • __global__ pour un kernel appelable uniquement depuis le CPU
    • __device__ __global__ pour un kernel appelable par le CPU et le GPU
  • Pas d’accès direct à la mémoire centrale de l’ordinateur (RAM)
  • Retour void obligatoire
  • Pas d’arguments variables (varargs)
  • Pas de récursivité
  • Pas de variables statiques

Le lancement d’un kernel s’effectue de la façon suivante :

myKernel <<< dimGrid, dimBlock [, dimMem ] >>>(params);

avec :

  • dimGrid : taille de la grille (en nombre de blocs)
  • dimBlock : taille de chaque bloc (en nombre de threads)
  • dimMem (optionnel) : taille de la mémoire partagée allouée par bloc

Le lancement d’un kernel est non bloquant pour le thread qui l’exécute.


5.2 Exemple

Comme exemple simple, voici 2 codes chargés d’incrémenter de 1 chaque case d’un tableau.

5.2.1 Code CPU

void main()
{
int a[N] = {0};
inc_cpu(&a, N);
}
void inc_cpu(int* a, int N)
{
int idx ;
for (idx=0 ; idx < N ; idx++)
{
a[idx] = a[idx] + 1 ;
}
}

5.2.2 Code GPU

void main()
{

dim3 dimBlock(blocksize);
dim3 dimGrid( ceil(N/(float)blocksize));

inc_gpu <<< dimGrid, dimBlock >>> (a, N);
}
__global__ void inc_gpu(int* a, int N)
{
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx < N)
{
a[idx] = a[idx] + 1;
}
}

Dans cette portion de code, on déclare un kernel qui dans un premier temps calcule son indice de thread dans sa grille.
Ensuite, il se sert de cet indice pour incrémenter la case correspondante dans le tableau.
Ainsi dans le thread principal, on lance l’exécution du kernel avec autant de threads que de ase du tableau à incrémenter.

5.2 FONCTIONNEMENT DU COMPILATEUR

La compilation est effectuée en plusieurs phases :

Le code exécuté par le CPU, qui représente la partie séquentielle du code est extrait des fichiers sources et est compilé avec le compilateur standard.

Le code exécuté par le GPU, qui est fortement parallèle, est extrait et converti dans un langage intermédiaire, proche d’un code assembleur, nommé PTX.
Certaines instructions ou fonctionnalités ne sont disponibles que pour certaines générations de cartes, seront détecté à partir du code PTX, et optimisé si nécessaire.
Le NVIDIA CUDA Compiler, NVCC, optimisera donc le code suivant le GPU cible.

Les 2 codes sont regroupés au sein d’un seul et même exécutable.

Principe de compilation CUDA
Principe de compilation CUDA

Mémoire

Localisation

Cachée

Accès

Portée

Registre

chipset

Non

Lecture/Ecriture

1 seul thread

Locale

DRAM

Non

Lecture/Ecriture

1 seul thread

Partagée

chipset

Non indiqué

Lecture/Ecriture

Tous les threads du bloc

Globale

DRAM

Non

Lecture/Ecriture

Tous les threads + hôte

Constante

DRAM

Oui

Lecture

Tous les threads + hôte

Texture

DRAM

Oui

Lecture

Tous les threads + hôte

6 réflexions sur « CUDA »

  1. Bonjour,
    je souhaite savoir quels sont les outils et comment faire les configurations s’il y a lieu de faire, à fin programmer en java en utilisant CUDA?
    j’ai un windows xp pack2
    carte graphique NVIDIA GeForce Go 7300
    1 Go de RAM
    merci à l’avance.
    Cordialement.

  2. Bonjour, il y a une faute en première page, je cite :
    « le code devant s’exécuter sur le GPU est en fait exécuté sur le GPU »
    -> est en fait exécuté sur le CPU.

    Voila merci pour l’article sinon 🙂

  3. pouvez vous nous indiquer les étapes à suivre pour utiliser cuda avec Visual studio 2010 ou bien 2008 et merci d’avance

Laisser un commentaire