161 votes

Comment CUDA Blocs/Chaines/Threads carte sur CUDA Cores?

J'ai été en utilisant CUDA pour quelques semaines, mais j'ai quelques doutes au sujet de l'allocation de blocs/chaines/thread. J'étudie l'architecture à partir d'un point de vue didactique (projet universitaire), afin d'atteindre des performances de pointe n'est pas ma préoccupation.

Tout d'abord, je voudrais comprendre si je suis ces faits:

A. Le programmeur écrit un noyau, et d'organiser son exécution dans une grille de thread se bloque.

B. Chaque bloc est assigné à une Streaming Multiprocesseur (SM). Une fois attribué, il ne peut pas migrer vers un autre SM.

C. Chaque SM divise ses propres blocs dans les Croisements (actuellement avec une taille maximale de 32 threads). Tous les threads d'un warp exécute simultanément sur les ressources de la SM.

D. L'exécution d'un thread est exécuté par le CUDA Cores contenues dans le SM. Il n'y a aucune correspondance entre les threads et les cœurs.

E. Si une chaine contient 20 thread, mais actuellement il y a seulement 16 cœurs disponibles, la chaîne ne sera pas exécuté.

F. d'autre part, si un bloc contient 48 threads, il sera divisé en 2 chaînes et elles s'exécutent en parallèle à condition que la mémoire disponible est suffisante.

G. Si un thread démarre sur un tronc, puis il est bloqué pour l'accès à la mémoire ou pour une longue opération de virgule flottante, son exécution pourrait reprendre sur une autre base.

Sont-ils corrects?

Maintenant, j'ai une GeForce 560 Ti ainsi, selon les spécifications qu'il est équipé de 8 cm, contenant chacune des 48 CUDA cores (384 cœurs au total).

Mon but est de faire en sorte que chaque de base de l'architecture exécute les MÊMES instructions. En supposant que mon code ne nécessite pas de s'inscrire que ceux disponibles dans chaque SM, j'ai imaginé des approches différentes:

  1. J'ai créer 8 blocs de 48 fils de chaque, de sorte que chaque SM a 1 bloc à exécuter. Dans ce cas, l'48 threads exécutent en parallèle dans le SM (en exploiter toutes les 48 cœurs disponibles pour eux)?

  2. Quelle est la différence si je me lance 64 blocs de 6 fils? (En supposant qu'ils seront cartographiés de manière uniforme entre les SMs)

  3. Si je "immerger" le CPU avec le travail (création de 1024 blocs de 1024 thread, par exemple) est-il raisonnable de supposer que tous les coeurs dans l'architecture sera utilisé à un certain point, et d'effectuer les mêmes calculs (en supposant que les fils ne jamais décrochage)?

  4. Est-il possible de vérifier ces situations à l'aide du générateur de profils?

  5. Est-il une référence pour ce genre de choses? J'ai lu le guide de Programmation CUDA et les chapitres consacrés à l'architecture matérielle dans "la Programmation des Processeurs Massivement Parallèles" et "CUDA la conception de l'Application et du développement"; mais je ne pouvais pas obtenir une réponse précise.

Je vous remercie pour votre temps.

136voto

Greg Smith Points 5397

Deux des meilleures références sont

  1. NVIDIA Fermi Calculer livre Blanc de l'Architecture
  2. GF104 Examens

Je vais essayer de répondre à chacune de vos questions.

Le programmeur divise le travail en fils, les fils de discussion dans thread se bloque, et le thread se bloque dans les grilles. Les tâches de calcul distributeur alloue thread se bloque à la diffusion des Multiprocesseurs (SMs). Une fois qu'un thread bloc est distribuée à un SM les ressources pour le fil de bloc sont attribués (croisements et de la mémoire partagée) et les threads sont divisés en groupes de 32 threads appelé les croisements. Une fois qu'une chaine est alloué, il est appelé un actif de la chaine. Les deux warp planificateurs de choisir deux chaines par cycle et d'expédition chaînes à unités d'exécution. Pour plus de détails sur les unités d'exécution et des instructions d'expédition voir 1 p.7 à 10 et 2.

D'. Il y a une correspondance entre laneid (fils de l'indice dans une chaine) et d'un noyau.

E'. Si une chaine contient moins de 32 threads, il sera dans la plupart des cas être exécutée de la même manière que si elle dispose de 32 threads. Les croisements peuvent avoir moins de 32 threads actifs pour plusieurs raisons: le nombre de threads par bloc n'est pas divisible par 32, le programme d'exécution d'une divergence de blocage de façon à ce fils qui n'a pas pris le chemin d'accès actuel sont marqué comme inactif, ou d'un fil dans le warp est sorti.

F'. Un thread bloc sera divisé en WarpsPerBlock = (ThreadsPerBlock + WarpSize - 1) / WarpSize Il n'est pas nécessaire pour la courbure des planificateurs pour sélectionner les deux courbures de la même thread bloc. G'. Une unité d'exécution ne se bloque pas sur une opération de mémoire. Si une ressource n'est pas disponible lorsqu'une instruction est prête à être expédiée, le cours sera distribué à nouveau dans l'avenir, lorsque la ressource est disponible. Les croisements peuvent décrochage des barrières, sur les opérations de mémoire, la texture des opérations, les dépendances de données, ... Un blocage de courbure est pas admissible à être sélectionné par la courbure du planificateur. Sur Fermi, il est utile d'avoir au moins 2 chaînes par cycle, de sorte que la courbure planificateur peut émettre une instruction.

Voir référence 2 les différences entre une GTX480 et GTX560.

Si vous lisez les documents de référence (quelques minutes) je pense que vous trouverez que votre objectif n'a pas de sens. Je vais essayer de répondre à vos points.

1'. Si vous lancez le noyau<<<8, 48>>> vous obtiendrez 8 pâtés de maisons, chacune avec 2 chaînes de 32 et 16 threads. Il n'y a aucune garantie que ces 8 chaines seront affectés à différents SMs. Si 2 chaînes sont alloués à un SM, alors il est possible que chaque chaine planificateur pouvez sélectionner une chaîne et en exécution de la chaîne. Vous utiliserez uniquement 32 de 48 cœurs.

2'. Il y a une grande différence entre les 8 blocs de 48 threads et 64 blocs de 6 fils. Supposons que votre noyau a pas de divergence et chaque thread s'exécute 10 instructions.

8 blocs avec 48 threads = 16 chaines * 10 instructions = 160 instructions 64 blocs avec 6 threads = 64 chaines * 10 instructions = 640 instructions

Afin d'obtenir une efficacité optimale de la division du travail doit être un multiple de 32 threads. Le matériel ne sera pas fusionner fils de chaines différentes.

3'. Une GTX560 peut avoir 8 cm * 8 blocs = 64 blocs à un moment ou 8 cm * 48 chaines = 512 chaînes si le noyau n'est pas au maximum de registres ou de la mémoire partagée. À un moment donné sur une partie du travail sera actif sur SMs. Chaque SM a plusieurs unités d'exécution (plus de CUDA cores). Les ressources sont utilisées à un moment donné dépend de la courbure de planificateurs et d'instructions de mélange de l'application. Si vous ne le faites pas TEX opérations TEX unités sera inactif. Si vous ne faites pas un spécial opération de virgule flottante le SUFU unités d'inactivité.

4'. Parallel Nsight et le Visual Profiler montrer un. exécuté CIB b. délivré de la CIB c. active chaînes par cycle actif d. admissibles chaînes par cycle actif (Nsight seulement) e. la courbure de décrochage raisons (Nsight seulement) f. threads actifs par instruction exécutée Le profiler ne pas afficher le pourcentage d'utilisation de l'une des unités d'exécution. Pour GTX560 une estimation approximative serait IssuedIPC / MaxIPC. Pour MaxIPC assumer GF100 (GTX480) est de 2 GF10x (GTX560) est de 4, mais la cible est 3 est une meilleure cible.

9voto

Andrej Points 57

"E. Si une chaine contient 20 thread, mais actuellement il y a seulement 16 cœurs disponibles, la chaîne ne sera pas exécuté."

est incorrect en raison du fait que la chaîne elle-même représente un seul core, et peut fonctionner jusqu'à 32 threads en même temps - un seul noyau peut fonctionner 32 threads. Une simple chaîne ne peut pas utiliser plus qu'un seul cœur. Vous pouvez avoir jusqu'à 48 active chaînes par multiprocesseur et il est égal à 1536 threads.

source: http://developer.download.nvidia.com/CUDA/training/cuda_webinars_WarpsAndOccupancy.pdf

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X