| ||||||||
Très simplement, un kernel est une fonction exécutée sur le GPU. Il en existe différent types, qualifiés de :
Le premier correspond à un kernel exécuté sur le GPU mais appelé par le CPU ; le deuxième, à un kernel exécuté et appelé par le GPU ; le troisième, à une fonction exécutée et appelée par le CPU. Ce dernier n'est pas obligatoire : c'est le mode de fonctionnement par défaut. Un kernel ne s'appelle pas de la même manière qu'une fonction. Voici un appel de fonction. Appel de fonction :
Mais avant de vous parler de l'appel d'un kernel, il faut que vous compreniez bien le mode de fonctionnement d'un GPU. Une grille représente la totalité de la tâche à effectuer. Chaque grille peut être divisée en un ou plusieurs blocs, chacun exécutant plusieurs threads. Un thread sur un GPU n'a pas le même sens qu'un thread sur le CPU. Sur un GPU, il s'agit de la plus petite subdivision de la tâche à effectuer. Un appel de kernel se fait en spécifiant 2 paramètres entre triples chevrons précédant les paramètres passés au kernel.
Les valeurs à appliquer dépendent simultanément du problème à résoudre (choix des dimensions des blocs) et du matériel utilisé (nombre de threads par bloc). Choisir un nombre de threads supérieurs à la quantité nativement supportée entraînera une perte de performances. Cette notation permet ainsi d'adapter dynamiquement le programme aux matériels passés, présents et futurs. Chaque kernel dispose de variables implicites en lecture seule (toutes de type dim3).
La grille est ici considérée comme un seul et unique bloc à une seule dimension.
Dans le cas où la grille est sous-divisée en N blocs (tous de 1 dimension), l'index pourrait être trouvé de la manière suivante.
Les variables doivent être qualifiées, pour définir leur lieu de résidence : voyez la section qui y est réservée. Les paramètres entre chevrons sont requis, car le kernel est de type __global__. S'il était d'un autre type, ils n'auraient pas dû être précisés ! | ||||||||
|