web-dev-qa-db-fra.com

Quel est le but d'utiliser plusieurs drapeaux "Arch" dans le compilateur NVCC de Nvidia?

J'ai récemment compris comment NVCC compile le code de périphérique CUDA pour différentes architectures de calcul.

Si je comprends bien, en utilisant l'option -gencode de NVCC, "Arch" est l'architecture de calcul minimale requise par l'application du programmeur, ainsi que l'architecture de calcul de périphérique minimale pour laquelle le compilateur JIT de NVCC compilera le code PTX. 

Je comprends également que le paramètre "code" de -gencode est l'architecture de calcul pour laquelle NVCC compile complètement l'application, de sorte qu'aucune compilation JIT n'est nécessaire.

Après inspection de divers fichiers Makefiles du projet CUDA, j'ai constaté les événements suivants régulièrement:

-gencode Arch=compute_20,code=sm_20
-gencode Arch=compute_20,code=sm_21
-gencode Arch=compute_21,code=sm_21

et après quelques lectures, j'ai trouvé que plusieurs architectures de périphériques pouvaient être compilées dans un seul fichier binaire - dans ce cas, sm_20, sm_21.

Mes questions sont pourquoi tant de paires Arch/code sont-elles nécessaires? Toutes les valeurs de "Arch" sont-elles utilisées dans ce qui précède?

quelle est la différence entre cela et dire:

-Arch compute_20
-code sm_20
-code sm_21

La première architecture virtuelle dans les champs "Arch" est-elle sélectionnée automatiquement ou existe-t-il un autre comportement obscur?

Existe-t-il d'autres comportements de compilation et d'exécution dont je devrais être au courant?

J'ai lu le manuel, http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#gpu-compilation et je ne comprends toujours pas ce qu'il se passe lors de la compilation ou d'exécution.

29
James Paul Turner

En gros, le flux de compilation du code est le suivant:

CUDA C/C++ source de code de périphérique -> PTX -> SASS

L’architecture virtuelle (par exemple, compute_20, quelle que soit la valeur spécifiée par -Arch compute...) détermine le type de code PTX qui sera généré. Les commutateurs supplémentaires (par exemple -code sm_21) déterminent le type de code SASS qui sera généré. SASS est en réalité un code d'objet exécutable pour un GPU (langage machine). Un exécutable peut contenir plusieurs versions de SASS et/ou PTX. Il existe un mécanisme de chargeur d'exécution qui sélectionne les versions appropriées en fonction du GPU réellement utilisé.

Comme vous l'avez souligné, l'une des fonctionnalités pratiques du fonctionnement du processeur graphique est la compilation JIT. La compilation JIT sera effectuée par le pilote GPU (ne nécessite pas l'installation de la boîte à outils CUDA) chaque fois qu'un code PTX approprié est disponible, mais pas un code SASS approprié.

L’avantage d’inclure plusieurs architectures virtuelles (c’est-à-dire plusieurs versions de PTX) est donc que vous avez une compatibilité exécutable avec un plus grand nombre de périphériques GPU cibles (bien que certains périphériques puissent déclencher une compilation JIT pour créer le SASS nécessaire).

L’inclusion de plusieurs "cibles GPU réelles" (c’est-à-dire plusieurs versions de SASS) présente l’avantage de pouvoir éviter l’étape de compilation JIT lorsqu’un de ces équipements cibles est présent.

Si vous spécifiez un ensemble d'options incorrect, il est possible de créer un exécutable qui ne s'exécutera pas (correctement) sur un GPU particulier.

Un inconvénient possible de spécifier un grand nombre de ces options est une taille de code démesurée. Un autre inconvénient possible est le temps de compilation, qui sera généralement plus long si vous spécifiez plus d'options.

Il est également possible de créer des fichiers exécutables ne contenant pas de PTX, ce qui peut intéresser ceux qui cherchent à masquer leur propriété intellectuelle.

La création de PTX adapté à JIT doit être effectuée en en spécifiant une architecture virtuelle pour le commutateur code.

37
Robert Crovella

Le but de plusieurs indicateurs -Arch est d'utiliser la macro __CUDA_Arch__ pour la compilation conditionnelle (c'est-à-dire, en utilisant #ifdef) de chemins de code optimisés différemment.

Voir ici: http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#virtual-architecture-identification-macro

1
Aleksandr Dubinsky