Implémentation d'algorithmes via des shaders de calcul vs des shaders de pipeline

10

Avec la disponibilité des shaders de calcul pour DirectX et OpenGL, il est désormais possible d'implémenter de nombreux algorithmes sans passer par le pipeline de rastérisation et d'utiliser à la place l'informatique à usage général sur le GPU pour résoudre le problème.

Pour certains algorithmes, cela semble devenir la solution canonique intuitive car ils ne sont pas intrinsèquement basés sur la pixellisation, et les shaders basés sur la pixellisation semblent être une solution de contournement pour exploiter la puissance du GPU (exemple simple: créer une texture de bruit. Aucun quad n'a besoin d'être pixellisé ici ).

Étant donné un algorithme qui peut être mis en œuvre dans les deux sens, y a-t-il des avantages de performance (potentiels) généraux par rapport à l'utilisation de shaders de calcul par rapport à la voie normale? Y a-t-il des inconvénients que nous devrions surveiller (par exemple, y a-t-il une sorte de surcharge inhabituelle pour passer de / à des shaders de calcul lors de l'exécution)?

Y a-t-il peut-être d'autres avantages ou inconvénients à considérer lors du choix entre les deux?

TravisG
la source
Si la balise de performance est effectivement pertinente, pensez à regarder cette vidéo de l'article "Cloth Simulation" de Game Engine Gems de Marco Fratarcangeli: youtube.com/watch?v=anNClcux4JQ . Vous pouvez lire les commentaires et découvrir une chose gênante: l'implémentation basée sur GLSL / shader était plus rapide que l'utilisation de CUDA ou OpenCL (cette dernière en raison de la mauvaise prise en charge des pilotes à l'époque, en 2010). Il y a certaines différences de bas niveau qui font la différence.
teodron
@teodron Je n'ai pas de gemmes GPU disponibles et je ne trouve pas le code source. L'auteur a-t-il réellement utilisé des nuanceurs GLSL vertex + pixel ou at-il utilisé des nuanceurs de calcul GLSL?
TravisG
Oui! Avant CUDA, c'est ainsi que la communauté implémentait les fonctionnalités GPGPU. Voici un lien vers OpenCloth pour voir comment on peut réaliser cela en utilisant du GLSL OU du Cuda pur: code.google.com/p/opencloth/source/browse/trunk/…
teodron

Réponses:

7

Il n'y a pas de bonne réponse si vous souhaitez bénéficier directement de l'approche de calcul shadrs / GPGPU, cela dépend fortement du type d'algorithme que vous mettez en œuvre, les shaders de calcul et CUDA / OpenCL sont une approche plus généralisée pour surmonter certaines des limitations de ces vieilles langues d'ombrage piratent. les avantages les plus importants que vous obtiendrez:

  • Accès aux informations spatiales. dans l'ancien hack GLSL (enfin, c'était un hack!) ne donne que peu d'informations sur les fragments voisins car il utilise des coordonnées de texture. Dans les shaders de calcul / CUDA / OpenCL, l'accès aux informations spatiales est beaucoup plus flexible, vous pouvez désormais implémenter des algorithmes comme l' égalisation d'histogramme sur le GPU avec un accès de texture / tampon non ordonné.
  • Vous donne la synchronisation des threads et atomique .
  • Espace de calcul: l'ancien hack GLSL connectera en dur l'espace de calcul sommet / fragment à votre shader. Le shader de fragments fonctionnera avec le nombre de fragments, le shader de vertex fonctionnera avec le nombre de sommets. Dans le shader de calcul, vous définissez votre propre espace.
  • Évolutivité : votre shader de calcul / CUDA / OpenCL peut évoluer jusqu'au nombre de SM GPU (Streaming Multiprocessor) disponibles contrairement à votre ancien shader GLSL qui devrait être exécuté sur le même SM. (Sur la base des commentaires de Nathan Reed, il dit que ce n'est pas vrai et que les shaders devraient évoluer aussi bien que les shaders de calcul. Je ne suis toujours pas sûr d'avoir besoin de vérifier la documentation).
  • Changement de contexte : il devrait y avoir un changement de contexte, mais je dirais que cela dépend de l'application, donc votre meilleur pari est de profiler votre application.

Eh bien, à mon avis , si vous voulez suivre la voie des shaders de calcul, même si certains algorithmes peuvent être plus adaptés, il y a certaines considérations que vous devez prendre en compte:

  1. Matériel et compatibilité descendante . Les shaders de calcul ne sont disponibles que dans du matériel plus récent et si vous optez pour un produit commercial (par exemple un jeu), vous devez vous attendre à ce que de nombreux utilisateurs ne soient pas en mesure d'exécuter votre produit.
  2. Vous avez généralement besoin de connaissances supplémentaires en architecture GPU / CPU , en programmation parallèle et en multithreading (par exemple, partage de mémoire, cohérence de la mémoire, synchronisation des threads, atomique et son effet sur les performances) que vous n'avez généralement pas besoin d'utiliser un shader rounte normal .
  3. Ressources d'apprentissage , par expérience, il y a beaucoup moins de ressources d'apprentissage pour les shaders de calcul, OpenCL et CUDA (qui offrent également l'interopérabilité OpenGL) que la route des shaders habituelle.
  4. Outils de débogage , avec le manque de débogage approprié, le développement d'outils peut devenir beaucoup plus difficile que la plupart des shaders, au moins les shaders peuvent être débogués visuellement.
  5. Je m'attends à ce que les shaders de calcul donnent de meilleures performances que le même algorithme dans d'autres shaders; si elles ont été faites correctement en tenant compte des choses du point 2, car elles ont été conçues pour éviter les étapes supplémentaires pour le rendu graphique. Mais je n'ai aucune preuve concrète pour étayer ma demande.
  6. Vous devriez également envisager CUUDA / OpenCL pour GPGPU si vous suivez cette voie.

Néanmoins, je suis sûr que c'est formidable pour l'avenir et que ce sera une excellente expérience d'apprentissage. Bonne chance!

concept3d
la source
Je pense que l'OP pourrait se demander ceci: pourquoi résoudre un problème en utilisant des shaders GLSL purs vs le coder dans CUDA? Il y a un article de Game Programming Gems concernant la simulation de tissu où l'auteur fait exactement cela. Et l'ancienne méthode GLSL hacky est meilleure que la méthode CUDA en termes de performances. Vous devriez probablement indiquer pourquoi si vous avez une idée de pourquoi.
teodron
2
Je ne pense pas que votre point d'évolutivité soit correct - les shaders de vertex et de fragments sont tout aussi capables de s'adapter à l'ensemble du GPU que les shaders de calcul. En fait, le calcul des shaders peut être plus difficile à mettre à l'échelle, car la taille du groupe de threads et l'utilisation de la mémoire partagée peuvent imposer des limites supplémentaires sur le nombre de threads de shader pouvant être exécutés à la fois.
Nathan Reed
2
De plus, si vous remplissez une texture (par exemple, générer du bruit ou faire un autre algorithme procédural), d'après mon expérience, un shader de fragment sera plus rapide qu'un shader de calcul si vous évaluez simplement une formule à chaque pixel. Je suppose que c'est parce que l'ordre des fragments correspond à l'ordre interne des pixels en mosaïque / swizzled, obtenant ainsi une meilleure localité de mémoire que le shader de calcul qui ne connaît pas cet ordre. Les shaders de calcul ne sont plus rapides que si vous pouvez utiliser leurs fonctionnalités spéciales, par exemple la mémoire partagée, pour accélérer beaucoup les choses par rapport à un shader de fragments.
Nathan Reed
2
OK, dernier commentaire. :) Je pense que la plupart des GPU actuels ont une sorte de changement de contexte ou de mode lorsqu'ils passent des graphiques au calcul et vice versa. Donc, si vous exécutez des shaders graphiques, puis distribuez un shader de calcul, puis exécutez quelques shaders graphiques supplémentaires, etc., vous subissez des pertes de performances lorsque vous changez d'avant en arrière. C'est quelque chose que vous auriez à profiler, mais cela pourrait être une autre raison de s'en tenir aux shaders graphiques dans un cas particulier.
Nathan Reed
@NathanReed merci pour les commentaires que je mettrai à jour ma réponse.
concept3d