web-dev-qa-db-fra.com

OpenCL: concept de groupe de travail

Je ne comprends pas vraiment le but des groupes de travail dans OpenCL.

Je comprends qu'il s'agit d'un groupe d'éléments de travail (supposément, des threads matériels), lesquels sont exécutés en parallèle.

Mais pourquoi ce besoin de subdivision plus grossière? Ne serait-il pas acceptable de n'avoir que la grille des fils (et, de facto, un seul W-G)?

Un groupe de travail doit-il correspondre exactement à un noyau physique? Par exemple, la carte TESLA c1060 aurait 240 cœurs. Comment les groupes de travail pourraient-ils correspondre à cela ??

De plus, pour autant que je sache, les éléments de travail à l'intérieur d'un groupe de travail peuvent être synchronisés grâce à des clôtures de mémoire. Les groupes de travail peuvent-ils se synchroniser ou est-ce même nécessaire? Se parlent-ils via la mémoire partagée ou est-ce uniquement pour les éléments de travail (pas sûr sur celui-ci)?

24
carmellose

Une partie de la confusion ici, je pense, tient à la terminologie. Ce que les gens du GPU appellent souvent les cœurs ne le sont pas vraiment, et ce que les gens du GPU appellent souvent les threads ne le sont que dans un certain sens.

Cores Un noyau, en termes de marketing GPU, peut faire référence à quelque chose comme un noyau de processeur, ou il peut se référer à une seule voie d'une unité SIMD - en fait, un processeur x86 à cœur unique serait composé de quatre cœurs type plus simple. C'est pourquoi le nombre de cœurs de GPU peut être si élevé. Ce n'est pas vraiment une comparaison juste, vous devez diviser par 16, 32 ou un nombre similaire pour obtenir un nombre de cœurs plus directement comparable.

Work-items Chaque work-item dans OpenCL est un thread en termes de flux de contrôle et de modèle de mémoire. Le matériel peut exécuter plusieurs éléments de travail sur un seul thread, et vous pouvez facilement l'imaginer en imaginant quatre éléments de travail OpenCL opérant sur les voies séparées d'un vecteur SSE. Il s'agirait simplement d'un compilateur ruse qui y parvient, et sur les GPU, il s'agit généralement d'un mélange de ruse du compilateur et d'assistance matérielle. OpenCL 2.0 expose en fait ce concept de thread matériel sous-jacent à travers des sous-groupes, il y a donc un autre niveau de hiérarchie à gérer.

Groupes de travail Chaque groupe de travail contient un ensemble d'éléments de travail qui doivent pouvoir progresser en présence d'obstacles. En pratique, cela signifie qu'il s'agit d'un ensemble, dont tous les états peuvent exister en même temps, de sorte que lorsqu'une primitive de synchronisation est rencontrée, il y a peu de surcharge lors de la commutation entre eux et il y a une garantie que la commutation est possible.

Un groupe de travail doit être mappé à une seule unité de calcul, ce qui signifie de manière réaliste qu'un groupe de travail entier tient sur une seule entité que les gens du CPU appellent un noyau - CUDA l'appellerait un multiprocesseur (selon la génération), AMD une unité de calcul et d'autres ont des noms différents. Cette localité d'exécution conduit à une synchronisation plus efficace, mais cela signifie également que l'ensemble des éléments de travail peut avoir accès à des unités de mémoire construites localement. On s'attend à ce qu'ils communiquent fréquemment, ou que des barrières ne soient pas utilisées, et pour rendre cette communication efficace, il peut y avoir des caches locaux (similaires à un CPU L1) ou des mémoires de bloc-notes (mémoire locale dans OpenCL).

Tant que des barrières sont utilisées, les groupes de travail peuvent se synchroniser en interne, entre les éléments de travail, en utilisant la mémoire locale ou en utilisant la mémoire globale. Les groupes de travail ne peuvent pas se synchroniser les uns avec les autres et la norme ne garantit pas la progression des groupes de travail les uns par rapport aux autres, ce qui rend impossible la création de primitives de verrouillage et de synchronisation portables.

Cela est dû en grande partie à l'histoire plutôt qu'au design. Le matériel GPU a longtemps été conçu pour construire des threads vectoriels et les affecter aux unités d'exécution d'une manière qui traite de manière optimale les triangles. OpenCL ne cherche pas à généraliser ce matériel pour être utile à d'autres choses, mais pas à le généraliser tellement qu'il devient inefficace à mettre en œuvre.

27
Lee

Il y a déjà beaucoup de bonnes réponses, pour une meilleure compréhension de la terminologie d'OpenCL cet article décrit en fait très bien tous les concepts.

6
chutsu

Un avantage des groupes de travail est qu'ils permettent d'utiliser la mémoire locale partagée comme cache défini par le programmeur. Une valeur lue dans la mémoire globale peut être stockée dans la mémoire locale du groupe de travail partagé, puis accessible rapidement par n'importe quel élément de travail du groupe de travail. Un bon exemple est le jeu de la vie: chaque cellule dépend d'elle-même et des 8 qui l'entourent. Si chaque élément de travail lisait ces informations, vous auriez 9 lectures de mémoire globale. En utilisant des groupes de travail et de la mémoire locale partagée, vous pouvez approcher 1x lectures de mémoire globale (approche uniquement car il y a des lectures redondantes sur les bords).

4
Dithermaster

L'utilisation des groupes de travail permet plus d'optimisation pour les compilateurs du noyau. En effet, les données ne sont pas transférées entre les groupes de travail. Selon le périphérique OpenCL utilisé, il peut y avoir des caches qui peuvent être utilisés pour les variables locales pour accélérer l'accès aux données. S'il n'y a qu'un seul groupe de travail, les variables locales seraient exactement les mêmes que les variables globales, ce qui entraînerait un accès plus lent aux données.

En outre, les périphériques OpenCL utilisent généralement des extensions SIMD (Single Instruction Multiple Data) pour obtenir un bon parallélisme. Un groupe de travail peut être exécuté en parallèle avec les extensions SIMD.

 Should a Work-Group exactly map to a physical core ?

Je pense que la seule façon de trouver la taille de groupe de travail la plus rapide est d'essayer différentes tailles de groupe de travail. Il est également possible d'interroger le CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE à partir du périphérique avec clGetKernelWorkGroupInfo . La taille la plus rapide doit être multiple de cela.

 Can work-groups synchronize or is that even needed ?

Groupes de travail ne peut pas être synchronisé . De cette façon, il n'y a pas de dépendances de données entre eux et ils peuvent également être exécutés séquentiellement, si cela est considéré comme le moyen le plus rapide de les exécuter. Pour obtenir le même résultat, que la synchronisation entre les groupes de travail, le noyau doit se diviser en plusieurs noyaux. Les variables peuvent être transférées entre les noyaux avec des tampons.

4
maZZZu