Le Compute Work Distributor planifiera un bloc de threads (CTA) sur un SM uniquement si le SM dispose de suffisamment de ressources pour le bloc de threads (mémoire partagée, warps, registres, barrières, ...). Les ressources au niveau du bloc de threads telles que la mémoire partagée sont allouées. L'allocation crée suffisamment de warps pour tous les threads dans le bloc de threads. Le gestionnaire de ressources alloue les warps en utilisant round robin aux sous-partitions du SM. Chaque sous-partition du SM contient un planificateur de warps, un fichier de registres et des unités d'exécution. Une fois qu'un warp est alloué à une sous-partition, il restera sur la sous-partition jusqu'à ce qu'il soit terminé ou préempté par un changement de contexte (architecture Pascal). Lors de la restauration du warp lors d'un changement de contexte, le warp sera restauré sur le même SM avec le même identifiant warp.
Lorsque tous les threads dans un warp sont terminés, le planificateur de warp attend que toutes les instructions en attente émises par le warp soient terminées, puis le gestionnaire de ressources libère les ressources au niveau du warp, y compris l'identifiant warp et le fichier de registres.
Lorsque tous les warps dans un bloc de threads sont terminés, alors les ressources au niveau du bloc sont libérées et le SM notifie le Compute Work Distributor que le bloc est terminé.
Une fois qu'un warp est alloué à une sous-partition et que toutes les ressources sont allouées, le warp est considéré comme actif, ce qui signifie que le planificateur de warp suit activement l'état du warp. À chaque cycle, le planificateur de warp détermine quels warps actifs sont bloqués et lesquels sont éligibles pour émettre une instruction. Le planificateur de warp choisit le warp éligible de priorité la plus élevée et émet 1 à 2 instructions consécutives à partir du warp. Les règles de double émission sont spécifiques à chaque architecture. Si un warp émet une lecture mémoire, il peut continuer à exécuter des instructions indépendantes jusqu'à ce qu'il atteigne une instruction dépendante. Le warp signalera alors une attente jusqu'à ce que la lecture soit terminée. Il en va de même pour les instructions mathématiques dépendantes. L'architecture du SM est conçu pour masquer à la fois la latence de l'ALU et de la mémoire en alternant par cycle entre les warps.
Cette réponse n'utilise pas le terme "cœur CUDA" car cela introduit un modèle mental incorrect. Les cœurs CUDA sont des unités d'exécution pipelinées en virgule flottante/entier simple précision. Le débit d'émission et la latence de dépendance sont spécifiques à chaque architecture. Chaque sous-partition de SM et SM dispose d'autres unités d'exécution, y compris des unités de chargement/stockage, des unités de virgule flottante double précision, des unités de virgule flottante demi-précision, des unités de branchement, etc.
Pour maximiser les performances, le développeur doit comprendre le compromis entre blocs, warps et registres/thread.
Le terme "occupation" est le ratio de warps actifs sur le nombre maximum de warps sur un SM. Les architectures Kepler - Pascal (à l'exception du GP100) ont 4 planificateurs de warps par SM. Le nombre minimal de warps par SM doit au moins être égal au nombre de planificateurs de warps. Si l'architecture a une latence d'exécution dépendante de 6 cycles (Maxwell et Pascal), alors vous aurez besoin d'au moins 6 warps par planificateur, ce qui donne 24 par SM (24 / 64 = 37,5 % d'occupation) pour couvrir la latence. Si les threads ont un parallélisme au niveau de l'instruction, cela pourrait être réduit. Presque tous les noyaux émettent des instructions à latence variable telles que des lectures mémoire pouvant prendre 80 à 1000 cycles. Cela nécessite plus de warps actifs par planificateur de warp pour masquer la latence. Pour chaque noyau, il existe un point de compromis entre le nombre de warps et d'autres ressources telles que la mémoire partagée ou les registres, donc optimiser pour une occupation de 100 % n'est pas conseillé car un autre sacrifice sera probablement fait. Le profil CUDA peut aider à identifier le débit d'émission des instructions, l'occupation et les raisons d'attente afin d'aider le développeur à déterminer cet équilibre.
La taille d'un bloc de threads peut avoir un impact sur les performances. Si le noyau a de grands blocs et utilise des barrières de synchronisation, alors les attentes de barrière peuvent être une des raisons de l'attente. Cela peut être atténué en réduisant les warps par bloc de threads.