Qu'est-ce que coalesced
dans une transaction de mémoire globale CUDA? Je ne pouvais pas comprendre même après avoir consulté mon guide CUDA. Comment faire? Dans l'exemple de matrice du guide de programmation CUDA, l'accès à la matrice ligne par ligne s'appelle coalesced
ou col .. by col .. s'appelle coalesced? Lequel est correct et pourquoi?
Réponses
Trop de publicités?Il est probable que cette information ne s'applique qu'à calculer capabality 1.x, ou cuda 2.0. Plus architectures récentes et cuda 3.0 ont plus sophistiquée de l'accès global à la mémoire et, en fait, "fusionné global des charges" ne sont même pas profilé pour ces puces.
Aussi, cette logique peut être appliquée à la mémoire partagée pour éviter de la banque des conflits.
Un coalisées de la mémoire d'opération est une opération dans laquelle tous les threads d'un demi-warp accès à la mémoire globale en même temps. C'est oversimple, mais la bonne façon de le faire est juste consécutives threads d'accéder consécutives adresses de mémoire.
Donc, si les threads 0, 1, 2, et 3 lire la mémoire globale 0x0, 0x4, 0x8, et 0xc, il devrait être fusionné lire.
Dans une matrice exemple, gardez à l'esprit que vous voulez que votre matrice de résider de façon linéaire dans la mémoire. Vous pouvez le faire quand vous le voulez, et votre accès à la mémoire doit refléter la façon dont votre matrice est aménagé. Ainsi, la matrice 3x4 ci-dessous
0 1 2 3
4 5 6 7
8 9 a b
pourrait être fait, rangée après rangée, comme cela, alors que (r,c) les cartes à mémoire (r*4 + c)
0 1 2 3 4 5 6 7 8 9 a b
Supposons que vous avez besoin pour accéder à l'élément une fois, et dire que vous avez quatre fils. Les threads seront utilisés pour quel élément? Probablement
thread 0: 0, 1, 2
thread 1: 3, 4, 5
thread 2: 6, 7, 8
thread 3: 9, a, b
ou
thread 0: 0, 4, 8
thread 1: 1, 5, 9
thread 2: 2, 6, a
thread 3: 3, 7, b
Qui est le meilleur? Ce qui aura pour résultat fusionné lit, et qui ne va pas?
De toute façon, chaque thread utilise trois accès. Regardons la première et de voir si les threads accèdent à la mémoire de façon consécutive. Dans la première option, le premier est de 0, 3, 6, 9. Non consécutif, pas fusionné. La deuxième option, c'est 0, 1, 2, 3. Consécutives! Fusionné! Yay!!!
Le mieux est sans doute d'écrire votre noyau, puis de profil, c'est pour voir si vous avez de la non-fusionné global des charges et des magasins.
La fusion de la mémoire est une technique qui permet une utilisation optimale de la mémoire globale de la bande passante. C'est, lors de fils parallèles de l'exécution de l'instruction de l'accès à des emplacements consécutifs dans la mémoire globale, le plus favorable à l'accès motif est réalisé.
L'exemple de la Figure ci-dessus permet d'expliquer le rappelait l'intégralité de l'accord:
Dans La Fig. (un), n vecteurs de longueur m sont stockés dans un mode linéaire. L'élément i du vecteur j est notée par v jje. Chaque thread dans le GPU noyau est attribué à un m-vecteur de longueur. Les Threads dans CUDA sont regroupés dans un tableau de blocs et chaque fil dans le GPU a un identifiant unique qui peut être défini comme l' indx = bd ×bx+tx
où bd
représente bloc de dimension, bx
indique l'index de bloc et tx
est le fil d'index dans chaque bloc.
Flèches verticales démontrer le cas en parallèle de threads d'accéder à la première des composantes de chaque vecteur, c'est à dire les adresses 0, m, 2m... de la mémoire. Comme indiqué dans la Fig. (a), dans ce cas, l'accès à la mémoire n'est pas consécutive. Par la réinitialisation de l'écart entre ces adresses (flèches rouges illustré dans la figure ci-dessus), l'accès à la mémoire devient fusionné.
Cependant, le problème est un peu difficile ici, depuis la taille de la résidence de threads par bloc GPU est limitée à bd
. Donc fusionné les données arrangement peut être fait en stockant les premiers éléments de la première bd
vecteurs dans l'ordre consécutif, suivie par les premiers éléments de la deuxième bd vecteurs et ainsi de suite. Le reste de vecteurs éléments sont stockés dans une façon similaire, comme indiqué dans la Fig. (b).
Dans les linéaires de stockage de données dans la Fig. (a), de la composante i (0 ≤ i < m) de vecteur indx
(0 ≤ indx < n) est adressée par m × indx +i
; le même composant dans le conflué
structure de stockage dans la Fig. (b) est traitée comme
(m × bd) ixC + bd × ixB + ixA
,
où ixC = floor[(m.indx + j )/(m.bd)]= bx
, ixB = j
et ixA = mod(indx,bd) = tx
.
En résumé, dans l'exemple de stocker un certain nombre de vecteurs de taille m, linéaire indexation est mappé à coalisées de l'indexation en fonction de:
m.indx +i −→ m.bd.bx +i .bd +tx
Ce réarrangement des données peut conduire à une augmentation significative de la bande passante mémoire du GPU, de la mémoire globale.
source: "basées sur le processeur d'accélération des calculs en éléments finis non-linéaires analyse de déformation." Revue internationale de méthodes numériques en génie biomédical (2013).
Si les threads d'un bloc sont l'accès consécutifs mondiale emplacements de mémoire, puis tous les accès sont combinés en une seule requête(ou agrégés) par le matériel. Dans la matrice exemple, les éléments de la matrice en ligne sont disposées linéairement, suivie par la ligne suivante, et ainsi de suite. Pour l'e.g matrice 2x2 et 2 threads d'un bloc, emplacements de mémoire sont organisées de manière à:
(0,0) (0,1) (1,0) (1,1)
Dans la ligne d'accès, thread1 accède à (0,0), (1,0), qui ne peut pas être fusionné. Dans la colonne de l'accès, thread1 accède à (0,0), (0,1), ce qui peut être fusionné parce qu'ils sont adjacents.
Les critères pour la coalescence sont bien documentées dans le CUDA 3.2 Guide de Programmation, Section G. 3.2. La version courte est comme suit: threads dans la courbure doit être accédant à la mémoire dans l'ordre, et les mots en cours d'accès doit >=32 bits. En outre, l'adresse de base étant accessible par la courbure doit être de 64, 128 ou 256 octets aligné pour 32, 64 et 128 bits accède aux, respectivement.
Tesla2 et Fermi matériel fait un bon travail de la coalescence de 8 et 16-bits accède, mais ils sont à éviter si vous voulez des pics de bande passante.
Noter que, malgré des améliorations dans Tesla2 et Fermi matériel, la coalescence est PAS obsolète. Même sur Tesla2 ou de Fermi du matériel de classe, à défaut de s'unir à la mémoire globale, les opérations peuvent entraîner un 2x performances. (Sur Fermi du matériel de classe, ce qui semble être vrai que si l'ECC est activé. Contigus mais uncoalesced mémoire transactions prendre environ 20% de hit sur de Fermi.)