J'utilise CUDA depuis quelques semaines, mais j'ai quelques doutes sur l'allocation des blocs / warps / thread. J'étudie l'architecture d'un point de vue didactique (projet universitaire), donc atteindre des performances optimales n'est pas ma préoccupation.
Tout d'abord, j'aimerais comprendre si j'ai bien compris ces faits:
Le programmeur écrit un noyau et organise son exécution dans une grille de blocs de threads.
Chaque bloc est affecté à un multiprocesseur de streaming (SM). Une fois attribué, il ne peut pas migrer vers un autre SM.
Chaque SM divise ses propres blocs en Warps (actuellement avec une taille maximale de 32 threads). Tous les threads d'un warp s'exécutent simultanément sur les ressources du SM.
L'exécution réelle d'un thread est effectuée par les cœurs CUDA contenus dans le SM. Il n'y a pas de mappage spécifique entre les threads et les cœurs.
Si une chaîne contient 20 threads, mais qu'il n'y a actuellement que 16 cœurs disponibles, la chaîne ne fonctionnera pas.
Par contre si un bloc contient 48 threads, il sera divisé en 2 warps et ils s'exécuteront en parallèle à condition que suffisamment de mémoire soit disponible.
Si un thread démarre sur un cœur, alors il est bloqué pour l'accès à la mémoire ou pour une longue opération en virgule flottante, son exécution peut reprendre sur un cœur différent.
Ont-ils raison?
Maintenant, j'ai une GeForce 560 Ti donc selon les spécifications, elle est équipée de 8 SM, contenant chacun 48 cœurs CUDA (384 cœurs au total).
Mon objectif est de m'assurer que chaque cœur de l'architecture exécute les MÊMES instructions. En supposant que mon code ne nécessitera pas plus de registres que ceux disponibles dans chaque SM, j'ai imaginé différentes approches:
Je crée 8 blocs de 48 threads chacun, de sorte que chaque SM ait 1 bloc à exécuter. Dans ce cas, les 48 threads s'exécuteront-ils en parallèle dans le SM (en exploitant tous les 48 cœurs disponibles pour eux)?
Y a-t-il une différence si je lance 64 blocs de 6 threads? (En supposant qu'ils seront mappés uniformément parmi les SM)
Si je "submerge" le GPU dans un travail planifié (en créant 1024 blocs de 1024 threads chacun, par exemple), est-il raisonnable de supposer que tous les cœurs seront utilisés à un certain moment et effectueront les mêmes calculs (en supposant que les threads ne jamais caler)?
Existe-t-il un moyen de vérifier ces situations à l'aide du profileur?
Y a-t-il une référence pour ce truc? J'ai lu le guide de programmation CUDA et les chapitres consacrés à l'architecture matérielle dans "Programming Massively Parallel Processors" et "CUDA Application design and development"; mais je n'ai pas pu obtenir de réponse précise.