Poussée pour la programmation GPU

10

Je suis très nouveau dans la programmation GPGPU, alors pardonnez-moi si la question n'est pas particulièrement appropriée. D'après ce que je comprends, la programmation GPU est un travail d'ingénierie très complexe par rapport à la programmation CPU habituelle. Il faut faire très attention aux problèmes de divergence, de tuilage, d'allocation de mémoire épinglée et de chevauchement de la communication hôte-appareil / calcul de l'appareil.

Après avoir fait un peu de recherche, j'ai trouvé la bibliothèque de poussée qui semble essayer d'imiter C ++ STL. C'est assez sympa. Cependant, sur la base de mon expérience très limitée et ayant vu toute la micro-gestion nécessaire pour obtenir de bonnes performances, je suis un peu sceptique quant aux performances. La poussée peut-elle gérer efficacement toute la partie de programmation complexe en interne? Certaines bibliothèques très connues, telles que PETSc, semblent utiliser ce package, ce qui me fait croire qu'il le devrait.

Je me demandais si les personnes ayant plus d'expérience sur CUDA et poussées pourraient dire un mot ou deux sur les performances du package par rapport à la programmation CUDA de bas niveau. Quand puis-je utiliser la poussée et quand dois-je revenir à CUDA?

GradGuy
la source
Avez-vous envisagé ArrayFire?
arrayfire

Réponses:

2

Je n'ai pas d'expérience personnelle avec la poussée, mais j'utilise ViennaCL, qui est une autre bibliothèque GPU de haut niveau qui cache presque tous les détails. D'après mon analyse comparative personnelle, je peux voir des accélérations de 2x - 40x sur le calcul réel si vous ignorez le temps qu'il faut pour se déplacer dans la mémoire.

Lorsque vous devez utiliser le processeur contre la poussée contre CUDA, tout dépend du problème que vous résolvez, de vos compétences et du temps dont vous disposez. Je recommanderais de commencer par résoudre des problèmes simples avec les 3 méthodes pour voir leurs performances relatives. Ensuite, vous pouvez écrire votre logiciel réel d'une manière rapide, le comparer et appliquer la méthode gpu appropriée dans les domaines qui nécessitent une accélération, plutôt que de perdre votre temps à écrire un logiciel CUDA qui ne vous fera gagner que quelques minutes de temps d'exécution .

Godric Seer
la source
Cela me semble parfaitement logique. Il faut toujours profiler d'abord. Donc, dans votre exemple, l'accélération que vous avez obtenue provient de l'utilisation de ViennaCL. Avez-vous essayé directement OpenCL pour vérifier la différence?
GradGuy
Non, comme vous, je suis nouveau dans l'informatique GPU. Je prévois au cours des deux prochaines années d'élargir lentement mes compétences pour inclure CUDA et OpenCL, mais actuellement je n'utilise que la bibliothèque. La documentation de ViennaCL indique qu'une accélération supplémentaire serait possible avec une implémentation openCL réglée qui serait probablement de l'ordre d'un autre 2x-10x, mais j'ai appris que la bande passante mémoire est le gorille de 900 livres dans la salle qui définit vraiment vos performances.
Godric Seer
5

J'ai utilisé Thrust dans mon projet d'extension de cluster lié. Selon la situation, Thrust peut fonctionner aussi bien ou mieux qu'une implémentation de bas niveau que vous lancez vous-même (en particulier, le reducenoyau fonctionne assez bien pour moi). Cependant, la nature générique et la flexibilité de Thrust signifie qu'il doit parfois faire beaucoup de copie supplémentaire, de remplissage de tableau, etc., ce qui peut le ralentir un peu dans quelques cas extrêmes. La dernière fois que je l'ai utilisé, sortil était assez lent par rapport à d'autres bibliothèques telles que b40c ou mgpu. Cependant, NVIDIA a travaillé sur l'amélioration des performances algorithmiques de Thrust, ce qui pourrait être moins problématique à l'avenir.

Vous devriez essayer d'écrire votre code en utilisant à la fois Thrust et CUDA, puis en utilisant Visual Profiler pour déterminer ce qui est le mieux pour la tâche spécifique qui vous intéresse. S'il est probable que le transfert de mémoire prendra le temps le plus long de votre programme et Je ne veux pas avoir à me soucier d'optimiser vos propres noyaux pour les conflits bancaires, le nombre d'instructions, etc., alors j'utiliserais Thrust. Cela a également l'avantage de rendre votre code beaucoup moins verbeux et plus facile à lire pour les personnes qui ne sont pas familiarisées avec la programmation GPU.

citrons verts
la source
3

Le but de la poussée (comme la plupart des bibliothèques de modèles) est de fournir une abstraction de haut niveau, tout en préservant de bonnes, voire excellentes performances.

Je suggère de ne pas trop se soucier des performances, mais de se demander si

  • votre application peut être décrite en termes d'algorithmes implémentés en poussée, et si

  • vous aimez la possibilité d'écrire du code parallèle "générique", sans avoir à entrer dans les détails sanglants de trouver un mappage efficace à l'architecture matérielle / logicielle donnée.

Si vous répondez positivement aux deux questions, vous devriez être en mesure de mettre en œuvre votre programme avec moins d'efforts par rapport à une mise en œuvre CUDA uniquement. Ensuite, vous pouvez profiler votre application et décider s'il vaut la peine d'essayer d'améliorer les performances.

Cela dit, je dois avouer que je n'aime pas la programmation "générique", car je suis prêt à apprendre quelque chose de nouveau lorsque j'écris un programme. Je suivrais une autre voie: écrire une implémentation de prototype en python + numpy + scipy, puis ajouter des noyaux CUDA pour ces 1% - 2% du code qui a vraiment besoin d'être optimisé et qui peut être exécuté sur un GPU. Bien sûr, ce faisant, vous avez besoin d'une sorte de pré-science, car une mauvaise décision dans la phase de prototypage (par exemple une structure de données inadaptée aux noyaux CUDA) peut avoir des résultats terribles sur les performances. Habituellement, plus d'itérations sont nécessaires pour obtenir un bon code et rien ne garantit de faire mieux que la poussée.

Stefano M
la source