cuda alignement de la mémoire
Dans mon code, je suis en utilisant les structures afin de faciliter le passage des arguments de fonctions (je n'utilise pas de tableaux de structures, mais plutôt des structures de tableaux en général).
Quand je suis dans cuda-gdb et j'examine le point dans un noyau où je donne des valeurs à une structure simple comme
struct pt{
int i;
int j;
int k;
}
même si je ne fais pas quelque chose de compliqué, et il est évident que les membres doivent avoir les valeurs nommé, je reçois...
Demandé pour la position 0 de la pile, la pile uniquement a 0 les éléments sur elle.
Donc je pense que même si c'est pas un tableau, peut-être il y a un problème avec l'alignement de la mémoire à ce point. J'ai donc modifier la définition dans le fichier d'en-tête de
struct __align__(16) pt{
int i;
int j;
int k;
}
mais ensuite, quand le compilateur essaie de compiler le serveur de fichiers de code qui utilisent les mêmes définitions, donne l'erreur suivante:
erreur: attendu unqualified-id avant d'numérique de la constante d'erreur: attendu
‘)’ avant numérique de la constante d'erreur: attendu constructeur, destructeur
ou de conversion de type avant ‘;’ token
alors, suis-je censé avoir deux définitions différentes de l'hôte et périphérique structures ???
Plus loin, je voudrais vous demander comment généraliser la logique de l'alignement. Je ne suis pas informaticien, donc les deux exemples dans le guide de programmation ne m'aident pas à obtenir la grande image.
Par exemple, comment les deux suivantes à être aligné? ou, comment faut-il une structure avec 6 chars être aligné? ou 4 entiers? encore une fois, je ne suis pas à l'aide de tableaux de ceux-ci, mais encore, je définir beaucoup de variables, avec ces structures à l'intérieur du noyau ou de _ appareil _ fonctions.
struct {
int a;
int b;
int c;
int d;
float* el;
} ;
struct {
int a;
int b
int c
int d
float* i;
float* j;
float* k;
} ;
Je vous remercie à l'avance pour tout conseil ou des conseils
- Je pense que vous êtes à la recherche pour cette [stackoverflow.com/questions/6978643/cuda-and-classes][1]répondu par @harrism lui-même. [1]: stackoverflow.com/questions/6978643/cuda-and-classes
Vous devez vous connecter pour publier un commentaire.
Il y a beaucoup de questions dans ce post. Depuis la programmation CUDA guide fait un assez bon travail d'expliquer l'alignement dans CUDA, je vais juste expliquer quelques choses qui ne sont pas évidentes dans le guide.
Tout d'abord, la raison de votre hôte compilateur vous donne des erreurs est parce que l'hôte compilateur ne sait pas ce que
__align(n)__
moyens, de sorte qu'il donne une erreur de syntaxe. Ce que vous avez besoin est de placer quelque chose comme ce qui suit dans un en-tête de votre projet.Pas, il suffit d'utiliser
MY_ALIGN(n)
, à l'instar de ceD'abord,
__align(n)__
(ou l'une de l'hôte compilateur saveurs), impose que la mémoire pour la structure commence à une adresse en mémoire qui est un multiple den
octets. Si la taille de la structure n'est pas un multiple den
, puis dans un tableau de ces structures, rembourrage sera inséré, de sorte que chaque structure est correctement aligné. Pour choisir une bonne valeur pourn
, vous souhaitez réduire la quantité de remplissage requis. Comme expliqué dans le guide de programmation, le matériel nécessite chaque thread lit des mots alignés à 1,2,4, 8 ou 16 octets. Alors...Dans ce cas, disons-nous choisir de 16 octets de l'alignement. Sur une machine 32 bits, le pointeur prend 4 octets, de sorte que la structure prend de 20 octets. De 16 octets de la géométrie des déchets
16 * (ceil(20/16) - 1) = 12
octets par struct. Sur une machine 64 bits, il sera un gaspillage de 8 octets par struct, en raison de l'octet de 8 pointeur. Nous pouvons réduire les déchets en utilisantMY_ALIGN(8)
à la place. La différence sera que le matériel vous devez utiliser 3 8 octets de charges au lieu de 2 sur 16 octets charge pour charger la structure de la mémoire. Si vous n'êtes pas un goulot d'étranglement par les charges, c'est probablement un bon compromis. Notez que vous ne voulez pas à aligner plus petit que 4 octets pour cette structure.Dans ce cas, avec 16 octets alignement de déchets à seulement 4 octets par structure sur les machines 32 bits, soit 8 sur les ordinateurs 64 bits. Elle aurait besoin de deux de 16 octets de charge (ou 3 sur une machine 64 bits). Si nous aligner sur 8 octets, nous pourrions éliminer les déchets entièrement avec 4 octets de l'alignement (8 octets sur les ordinateurs 64 bits), mais il en résulterait une charge excessive. De nouveau, les compromis.
Encore une fois, les compromis: soit des déchets de 8 octets par struct ou besoin de deux chargements par struct.
Pas de compromis ici.
MY_ALIGN(16)
.Hmmm, si vous n'êtes pas à l'aide de tableaux de ces derniers, alors vous ne pouvez pas besoin d'aligner à tous. Mais comment êtes-vous d'assigner à eux? Comme vous êtes probablement voir, tous les déchets est important de s'inquiéter, c'est une autre bonne raison de privilégier des structures de tableaux sur des tableaux de structures.
__declspec(align(n))
. le compilateur définit__INTEL_COMPILER
, de sorte que vous vous pourriez ajouter à votreMSVC
un. Et Clang définit__clang__
, et utilise GCC version (__attribute__((aligned(n)))
), donc vous pouvez ajouter il. qui couvre à peu près tous les grands (non spécialisés, c'est à dire le BRAS dont je ne connais pas du tout les compilateurs je m'en occupe 😉 j'ai eu du mal avec Intel, car elles définissent un tas de choses que vous ne s'attendrait pas. Je ne me souviens pas des détails, mais la solution est de vérifier d'abord.Ces jours-ci, vous devez utiliser le C++11
alignas
rédacteur de devis, qui est pris en charge parg++
(y compris les versions compatible avec les CUDA), et IIANM parnvcc
ainsi. Qui devraient vous sauver la nécessité de recourir à des macros.