J'ai remarqué que de nombreux programmes 3D effectuent normalement des calculs vectoriels / matriciels ainsi que des transformations géométriques sur le CPU. Quelqu'un a-t-il trouvé un avantage à déplacer ces calculs dans des vertex shaders sur le GPU?
De manière générale: les transformations de maillage se font sur le GPU. Vous envoyez la matrice de transformation au GPU et le shader l'applique à tous les sommets du maillage.
L'utilisation du GPU pour calculer la matrice elle-même est une question différente et est en fait plus lente sur le GPU car il y a tellement de valeurs stockées qui changent d'image en image qui sont nécessaires pour aider à déterminer la matrice de transformation finale. L'envoi de ces données vers et depuis le CPU - le GPU est lent. De plus, sur le CPU, les calculs sont effectués une seule fois, alors que sur le GPU, ils seraient effectués pour chaque sommet.
Wrt la partie "effectivement plus lent sur GPU"; c'est une déclaration très large. Si vous parlez de construire la matrice pour chaque sommet sur GPU, vos performances dépendront de vos goulots d'étranglement. Vous n'obtiendrez des performances plus lentes que si vous êtes lié ALU / registre sur le GPU, ce qui n'est pas nécessairement le cas. Faire exactement la même chose sur un processeur serait également plus lent dans ces scénarios de goulot d'étranglement. Un exemple où cela est couramment fait sur le GPU: les vertex shaders construisent des matrices d'espace de tangente de vertex à la volée pour économiser la bande passante de vertex fetch. Encore une fois, en fonction de vos goulots d'étranglement, donc YMMV.
jpaver
Je ne peux pas downvote, mais cette réponse devrait être downvote. Il est très faux de dire "en fait plus lent sur le GPU".
Adam
3
De nombreuses transformations géométriques peuvent être effectuées sur des processeurs non GPU, mais il faut tenir compte de la plate-forme cible. Votre kilométrage varie en fonction de la plateforme que vous ciblez et des goulots d'étranglement de cette plateforme.
Une considération est la bande passante du bus entre le périphérique qui génère la géométrie et le périphérique qui rend la géométrie.
Dans un système PC moderne typique, le CPU se trouve d'un côté du bus PCIe (http://en.wikipedia.org/wiki/PCI_Express), et le GPU est de l'autre. La seule façon de transférer des données générées par image du CPU vers le GPU (et vice-versa) est via ce bus. Cela signifie que vous pouvez être limité par la vitesse de transfert de ce bus. Si votre plate-forme cible a PCIe 2.x avec 16 voies, vous disposez d'une bande passante de 8 Go / s. En pratique, les transferts via PCIe ne sont pas efficaces à 100%, car une partie de la bande passante est consommée pour le protocole lors de vos transferts. Selon la taille de vos transferts, vous pourriez perdre 5 à 10% de votre bande passante uniquement sur la surcharge par paquet.
par exemple. Étant donné une plate-forme PC qui exécute PCIe 2.x avec 16 voies, combien de données pouvez-vous générer par trame pour l'alimentation du GPU? En supposant que vous souhaitez exécuter à 60 ips, cela se traduit par 8 Go / 60 = 136 Mo par trame pour PCIe 2.x. En multipliant par un facteur (invité) de 90% pour tenir compte de la surcharge de communication du pilote et de la surcharge du protocole de transfert PCIe, vous pouvez générer environ 120 Mo de données par trame sans être limité par la bande passante PCIe 2.x.
Une autre question à laquelle vous devez répondre: la génération de ces 120 Mo de données sera-t-elle facilement réalisable en 1 / 60e de seconde sur votre CPU cible? En vous rappelant que vous devez effectuer un certain nombre d'autres tâches de jeu sur votre CPU, vous pouvez manquer de temps pour générer les données transformées. En termes de débit ALU pur, cela peut vous limiter sur le processeur. En termes de bus CPU à sysmem, vous pouvez également être limité par la bande passante (qui varie, mais est d'environ ~ 8,5 Go / s sur les processeurs récents).
D'accord, alors quels facteurs le rendent plus viable à faire sur un GPU alors? Un facteur est la bande passante mémoire du GPU, qui est la bande passante entre le GPU et sa mémoire vidéo locale. Sur les GPU milieu de gamme contemporains, cette bande passante de la mémoire vidéo peut atteindre 200 Go / s (oui, c'est 25 fois la bande passante PCIe 2.x). Un autre facteur est que le GPU est massivement parallèle, possède des centaines d'ALU et est capable de masquer la latence d'accès à la mémoire en exécutant des milliers de threads à la fois.
Tous ces facteurs peuvent contribuer à la victoire évidente de pousser plus de travail sur le GPU, mais encore une fois YMMV selon votre plate-forme cible.
Qu'entendez-vous par «transformations de maillage»? Transformer la géométrie par un ensemble de matrices? De nos jours, la plupart des jeux permettent au GPU de gérer des transformations simples, des habillages, etc. Et la plupart d'entre eux utiliseront des vertex shaders pour le faire. Sur certaines plates-formes, vous n'avez pas de shaders, ou il y a d'autres avantages à faire ces choses sur le CPU. Par exemple, sur la PS3, vous pouvez alléger le RSX en laissant les SPU gérer le skinning et la transformation. Si vous effectuez un éclairage multi-passes, le skinning sur le CPU peut être avantageux, car vous ne devez le faire qu'une seule fois et soumettre les résultats à dessiner pour chaque passe de rendu. Il y a donc des exceptions, mais en général la plupart des jeux font ces choses sur le GPU et dans les shaders.
Ou vouliez-vous dire quelque chose de plus sophistiqué, comme utiliser le GPU pour les mathématiques vectorielles générales? De nos jours, nous avons des GPU à usage général qui peuvent exécuter du code C assez générique via des systèmes tels que CUDA. Il est possible d'en profiter pour les mathématiques vectorielles lourdes, et je sais qu'il existe des programmes qui font cela. Je n'ai cependant aucune expérience personnelle.
changé «transformation de maillage» en «transformation géométrique» pour aider à clarifier la question. j'attends également des opencl es, qui pourraient être disponibles au début de l'année prochaine.
zmdat
0
Il y a des situations où tout avoir rendu sur le GPU peut avoir du sens, mais vous ne pouvez pas définir de constantes à l'intérieur d'un shader et il n'y a vraiment aucun autre endroit pour les configurer sauf du côté CPU avant un appel de tirage.
Même si vous pouviez calculer vos constantes, comme les matrices de transformation osseuse, sur le GPU avec un programme d'initialisation personnalisé, vous ne le voudriez probablement pas. le GPU est vraiment bon en exécution parallèle, mais a une vitesse d'horloge beaucoup plus lente.
La transformation d'une hiérarchie n'est pas trivialement parallélisable, car les nœuds enfants dépendent des parents, mais la transformation de tous les sommets d'un maillage l'est, car les sommets sont indépendants du calcul les uns des autres.
De nombreuses transformations géométriques peuvent être effectuées sur des processeurs non GPU, mais il faut tenir compte de la plate-forme cible. Votre kilométrage varie en fonction de la plateforme que vous ciblez et des goulots d'étranglement de cette plateforme.
Une considération est la bande passante du bus entre le périphérique qui génère la géométrie et le périphérique qui rend la géométrie.
Dans un système PC moderne typique, le CPU se trouve d'un côté du bus PCIe (http://en.wikipedia.org/wiki/PCI_Express), et le GPU est de l'autre. La seule façon de transférer des données générées par image du CPU vers le GPU (et vice-versa) est via ce bus. Cela signifie que vous pouvez être limité par la vitesse de transfert de ce bus. Si votre plate-forme cible a PCIe 2.x avec 16 voies, vous disposez d'une bande passante de 8 Go / s. En pratique, les transferts via PCIe ne sont pas efficaces à 100%, car une partie de la bande passante est consommée pour le protocole lors de vos transferts. Selon la taille de vos transferts, vous pourriez perdre 5 à 10% de votre bande passante uniquement sur la surcharge par paquet.
par exemple. Étant donné une plate-forme PC qui exécute PCIe 2.x avec 16 voies, combien de données pouvez-vous générer par trame pour l'alimentation du GPU? En supposant que vous souhaitez exécuter à 60 ips, cela se traduit par 8 Go / 60 = 136 Mo par trame pour PCIe 2.x. En multipliant par un facteur (invité) de 90% pour tenir compte de la surcharge de communication du pilote et de la surcharge du protocole de transfert PCIe, vous pouvez générer environ 120 Mo de données par trame sans être limité par la bande passante PCIe 2.x.
Une autre question à laquelle vous devez répondre: la génération de ces 120 Mo de données sera-t-elle facilement réalisable en 1 / 60e de seconde sur votre CPU cible? En vous rappelant que vous devez effectuer un certain nombre d'autres tâches de jeu sur votre CPU, vous pouvez manquer de temps pour générer les données transformées. En termes de débit ALU pur, cela peut vous limiter sur le processeur. En termes de bus CPU à sysmem, vous pouvez également être limité par la bande passante (qui varie, mais est d'environ ~ 8,5 Go / s sur les processeurs récents).
D'accord, alors quels facteurs le rendent plus viable à faire sur un GPU alors? Un facteur est la bande passante mémoire du GPU, qui est la bande passante entre le GPU et sa mémoire vidéo locale. Sur les GPU milieu de gamme contemporains, cette bande passante de la mémoire vidéo peut atteindre 200 Go / s (oui, c'est 25 fois la bande passante PCIe 2.x). Un autre facteur est que le GPU est massivement parallèle, possède des centaines d'ALU et est capable de masquer la latence d'accès à la mémoire en exécutant des milliers de threads à la fois.
Tous ces facteurs peuvent contribuer à la victoire évidente de pousser plus de travail sur le GPU, mais encore une fois YMMV selon votre plate-forme cible.
la source
Qu'entendez-vous par «transformations de maillage»? Transformer la géométrie par un ensemble de matrices? De nos jours, la plupart des jeux permettent au GPU de gérer des transformations simples, des habillages, etc. Et la plupart d'entre eux utiliseront des vertex shaders pour le faire. Sur certaines plates-formes, vous n'avez pas de shaders, ou il y a d'autres avantages à faire ces choses sur le CPU. Par exemple, sur la PS3, vous pouvez alléger le RSX en laissant les SPU gérer le skinning et la transformation. Si vous effectuez un éclairage multi-passes, le skinning sur le CPU peut être avantageux, car vous ne devez le faire qu'une seule fois et soumettre les résultats à dessiner pour chaque passe de rendu. Il y a donc des exceptions, mais en général la plupart des jeux font ces choses sur le GPU et dans les shaders.
Ou vouliez-vous dire quelque chose de plus sophistiqué, comme utiliser le GPU pour les mathématiques vectorielles générales? De nos jours, nous avons des GPU à usage général qui peuvent exécuter du code C assez générique via des systèmes tels que CUDA. Il est possible d'en profiter pour les mathématiques vectorielles lourdes, et je sais qu'il existe des programmes qui font cela. Je n'ai cependant aucune expérience personnelle.
la source
Il y a des situations où tout avoir rendu sur le GPU peut avoir du sens, mais vous ne pouvez pas définir de constantes à l'intérieur d'un shader et il n'y a vraiment aucun autre endroit pour les configurer sauf du côté CPU avant un appel de tirage.
Même si vous pouviez calculer vos constantes, comme les matrices de transformation osseuse, sur le GPU avec un programme d'initialisation personnalisé, vous ne le voudriez probablement pas. le GPU est vraiment bon en exécution parallèle, mais a une vitesse d'horloge beaucoup plus lente.
La transformation d'une hiérarchie n'est pas trivialement parallélisable, car les nœuds enfants dépendent des parents, mais la transformation de tous les sommets d'un maillage l'est, car les sommets sont indépendants du calcul les uns des autres.
La règle générale est la suivante:
la source