IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

OpenGL Discussion :

Shaders simple et chute de perfs


Sujet :

OpenGL

  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2005
    Messages : 177
    Par défaut Shaders simple et chute de perfs
    Bonjour,

    Je fais un petit programme 3D qui utilise OpenGL, Je me suis dit pourquoi ne pas utiliser le pipeline programmable, et donc un pixel et un fragment shader. Je précise que je suis débutant en openGL que le programme en ce moment n’affiche que 1 carré coloré que je n’y ai pas encore intégré les VBO, et que je suis en fenêtré 512x512 (histoire de pouvoir voir ma console, comme vous l’imaginez il est loin d’être fini). Ma carte n’est pas des plus récente c’est une FX5700LE.

    Résulat
    Sans shaders je suis à + ou - 3750fps
    Avec shader, je suis à + ou - 1900fps

    Mon super vertex shader (qui ne fait rien en faite)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void main(void)
    {
       gl_Position = gl_Vertex;
    }
    Mon super fragment shader (qui ne fait que changer la couleur)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void main(void)
    {
       gl_FragColor = vec4(0.1, 0.8, 0.1,1.0);
    }
    Quel que soit la résolution mes perfs diminuent toujours d’a peu près 50%. Par contre si je change la taille de mon carrée les performances change rapidement. J’en conclu que c’est le nombre de pixel écrit qui me bloque et pas le calcule de vertex. Car le pipeline calcule toujours 4 vertex. Je peu rajouter du code dans le VS ça ne change rien au fps. Par contre si je modifie le FS, les perf varient fortement. J’en conclu donc que la chute de perf vient du FS.

    J’ai lu qu’en utilisant des autres type genre "half" ça pouvais booster les performances jusque 3 fois (source NVidia GPU guide). Mais dans tout les cas, je ne vois pas comment utiliser ça en GLSL (NVidia donne des infos que pour CG).

    Est-ce que pour vous cette chute de performance est normale ?
    Et si non , ce que j’espère, comment pourrais je optimiser mon fragment shader ?
    Me conseillez vous CG avec un type half pour ce genre de chose ?
    Il y a t'il des chose essentiel a faire avant de passer a un pipeline programmable ?

  2. #2
    Membre éprouvé Avatar de Harooold
    Homme Profil pro
    Ingénieur 3D temps réel
    Inscrit en
    Mars 2008
    Messages
    136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2008
    Messages : 136
    Par défaut
    Hello,

    Pour moi la chutte de perf est tout à fait normale.
    Pour simuler le pipeline par défaut d'opengl, le vertex shader doit juste faire la multiplication de la matrice modelview et projection (ce que tu ne fais pas dailleur ) et le fragment shader ne fait strictement rien ( vu que tu n'utilises pas l'éclairage et les textures pour l'instant je suppose ).

    Là tu fais un traitement dans le fragment shader, tu vas donc faire des opérations pour chaque pixel qui va être affiché, donc plus de boulot que si tu n'avais pas tes shaders. Ca serait plutot inquiétant si tu avais un gain de perfs :p Et oui, plus ton carré sera grand, enfin, grand sur l'écran, et plus ta résolution sera élevée, plus de pixels seront affichés et plus ton FPS chuttera.

    Corrige moi le vertex shader en multipliant ton gl_Vertex par la modelview et la matrice de projection, je te laisses chercher la syntaxe :p

    Personellement, je te conseillerai bien de ne pas te soucier des questions d'optimisation et compagnie. Les ordis ,même bas de gamme aujourdhui, sont suffisement puissants pour faire tourner sans problème tout ce que tu pourras faire durant ton apprentissage sans avoir à te soucier de l'optimiser.
    En gros, commence à te soucier du FPS quand ça commencera à lagger ( 10 -15 FPS ).

  3. #3
    Membre chevronné
    Inscrit en
    Février 2008
    Messages
    413
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Février 2008
    Messages : 413
    Par défaut
    et le fragment shader ne fait strictement rien ( vu que tu n'utilises pas l'éclairage et les textures pour l'instant je suppose ).
    en es-tu sûr Harooold? Pour pouvoir voir quelque chose à l'écran il faut au minimum donner une valeur à gl_FragColor, du moins c'est comme ca que je l'avais compris.

    Dans l'exemple d'Heptaeon, il donne une couleur fixe, donc son polygône prendra cette couleur uniformément. Il n'y pas plus simple et pourtant, comme tu l'as dit Haroold, plus ce polygône prendra de la place à l'écran, plus le fragment shader va être appelé et ralentir l'application.

    Je comprends cette logique quand le fragment shader a quelques calculs à faire, j'en ai d'ailleurs fait l'expérience moi même, mais dans le cas d'un shader aussi simple je ne comprends pas que la différence avec le mode sans shaders soit aussi importante. Car la partie "fixe" d'OpenGL, ce n'est rien d'autre que d'utiliser les shaders implémentés par défaut sur la carte graphique. Que font-ils donc autrement dans leurs shaders pour que ca soit plus rapide? ca ne peut pas être plus simple que de fixer une couleur par défaut.....

  4. #4
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2005
    Messages : 177
    Par défaut
    Citation Envoyé par ShevchenKik Voir le message
    en es-tu sûr Harooold? Pour pouvoir voir quelque chose à l'écran il faut au minimum donner une valeur à gl_FragColor, du moins c'est comme ca que je l'avais compris.

    Dans l'exemple d'Heptaeon, il donne une couleur fixe, donc son polygône prendra cette couleur uniformément. Il n'y pas plus simple et pourtant, comme tu l'as dit Haroold, plus ce polygône prendra de la place à l'écran, plus le fragment shader va être appelé et ralentir l'application.

    Je comprends cette logique quand le fragment shader a quelques calculs à faire, j'en ai d'ailleurs fait l'expérience moi même, mais dans le cas d'un shader aussi simple je ne comprends pas que la différence avec le mode sans shaders soit aussi importante. Car la partie "fixe" d'OpenGL, ce n'est rien d'autre que d'utiliser les shaders implémentés par défaut sur la carte graphique. Que font-ils donc autrement dans leurs shaders pour que ca soit plus rapide? ca ne peut pas être plus simple que de fixer une couleur par défaut.....
    J'avais eu les mêmes echos, Donc je m'attendais effectivement a un gain de perf. Je n'interpole pas les couleurs et pourtant c'est plus lent .

    Maintenant je suppose que chez NVidia qui a fait mes drivers ils ont mis un shader de base super bien optimisé.

    ps: je trouve d'ailleurs con que le GLSH utilise 1 float pour les couleur, alors que mes image me donnerons 1 byte par couleur et que l'affichage a 1 byte lui aussi par couleur.

    @Harooold
    Il n'y a pas de matrice ni rien car ce shader servira pour l'affichage de sprite de menu et autre donc ça me gênerais plutôt de la prendre en compte. Mon but était vraiment de libérer des ressources.

  5. #5
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Citation Envoyé par Heptaeon Voir le message
    Sans shaders je suis à + ou - 3750fps
    Avec shader, je suis à + ou - 1900fps
    3750 fps = 0.27 ms par frame
    1900 fps = 0.52 ms par frame

    Donc une perte de temps de 0.25 ms par frame, soit près de 40 fois moins de temps qu'un battement de paupière.

    Citation Envoyé par Heptaeon Voir le message
    Est-ce que pour vous cette chute de performance est normale ?
    Oui. Et franchement, je n'appelle pas ça une chute de performance. Il faut arrêter de penser en fps pour commencer à penser en spf. On parle quand même d'un quart de milliseconde là. Je dirais presque que c'est le temps qu'il faut à tes données pour être transférées, transformées et rendue sur l'écran. N'oublie pas que tu changes quand même la machine d'état OpenGL.

    Citation Envoyé par Heptaeon Voir le message
    Et si non , ce que j’espère, comment pourrais je optimiser mon fragment shader ?
    Le code le plus rapide est celui qui ne s'exécute pas

    Serieusement, tu veux optimiser quoi là ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void main(void)
    {
       gl_FragColor = vec4(0.1, 0.8, 0.1,1.0);
    }
    A part enlever la ligne, je ne vois pas.

    Plus sérieusement, si tu veux remplir une zone avec une couleur uniforme, ce n'est pas le fragment shader qu'il faut utiliser, c'est le vertex shader. Ici, tu dis à chaque pixel de prendre une couleur donnée. Le per-pixel lignthing, c'est bien mais bon, il faut quand même être un poil pratique... Ne t'etonne pas que ça prenne un peu de temps (mais soyons sérieux, on parle quand même de 25% d'une milliseconde...).

    ps: je trouve d'ailleurs con que le GLSH utilise 1 float pour les couleur, alors que mes image me donnerons 1 byte par couleur et que l'affichage a 1 byte lui aussi par couleur.
    Sauf que le GPU est optimisée pour traiter des float en grand nombre. Traiter des bytes lui coute "paradoxalement" beaucoup plus de temps.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  6. #6
    Membre chevronné
    Inscrit en
    Février 2008
    Messages
    413
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Février 2008
    Messages : 413
    Par défaut
    Emmanuel, bien sûr que 0.25ms ce n'est rien, et que la différence ne se ressentira pas dans l'application finale, mais là n'est pas la question, on essaie de comprendre ce qui se passe.

    Donc, je n'ai toujours pas compris pourquoi, en utilisant un fragment shader qui applique la même couleur à chaque pixel, c'est plus lent qu'en OpenGL "fixe", où le shader calcule quand meme plus de choses.

  7. #7
    Expert confirmé
    Avatar de raptor70
    Inscrit en
    Septembre 2005
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Septembre 2005
    Messages : 3 173
    Par défaut
    Citation Envoyé par ShevchenKik Voir le message
    Donc, je n'ai toujours pas compris pourquoi, en utilisant un fragment shader qui applique la même couleur à chaque pixel, c'est plus lent qu'en OpenGL "fixe", où le shader calcule quand meme plus de choses.

    Reflechi comment se compose tes deux pipelines :
    sans shader : opengl utilise directement la couleur passée par glColor
    avec shader : opengl charge le shader, (pour chaque pixel) recupère la couleur de glColor, assigne les 3 composantes pour la valeur du fragment(pixel),
    decharge le shader.

    Les shaders n'ont jamais été un gain de performance, au contraire. Ils permettent simplement de donner accès aux programmeurs au fonctionnalités interne à ta carte graphique en utilisant le GPU (rendu hardware). Sans shader, ce serait le CPU qui ferait (quasiement) tout (rendu software )

  8. #8
    Membre chevronné
    Inscrit en
    Février 2008
    Messages
    413
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Février 2008
    Messages : 413
    Par défaut
    OK merci pour tes précisions Raptor, là c'est plus clair et je me rends compte que je n'avais pas tout à fait compris où venaient s'intercaler les shaders dans le pipeline.

  9. #9
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2005
    Messages : 177
    Par défaut
    @Emmanuel Deloget
    Dans le monde de l'informatique une miliseconde est une éternité.

    Tu dit que ce code est impossible a optimisez ? Certain l'ont déjà fait justement, et c'est ce que j'aimerais comprendre. Ce qu'il faut regarder c'est que sur un code simple d'autre font 2 fois plus rapide que moi.

    Et pour finir en DX quant on change le shader pour un plus simple on peu gagner en performance (Ça le faisait en XNA).

    Donc on peu s'en voir 50% de ses perfs disparaitre ou se demander quoi ^^, moi j'ai choisi.

  10. #10
    Membre chevronné
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    366
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 366
    Par défaut
    Question Quizz : comment et quand tes shader sont ils compiles ? a chaque frame ?

    De plus pour avoir eu des soucis moi meme sur Fx5xxx il y a quelques annees (je me souviens plus trop mais de memoire il ya avait des problemes de supports de fonctions simple par le driver), je dirais que tu devrais mine de rien te rencarder sur les specificites memes de ton GPU

  11. #11
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2005
    Messages : 177
    Par défaut
    Citation Envoyé par smashy Voir le message
    Question Quizz : comment et quand tes shader sont ils compiles ? a chaque frame ?
    Une seul fois juste après avoir créer le context opengl (sinon j'ai pas les extention) après il y a 1 UseProgram. Dans la boucle de rendu j'ai meme pas le use XD j'ai sortit un maximum de chose.

    Justement le Half c'est une spécificité des FX .

  12. #12
    Membre chevronné
    Inscrit en
    Février 2008
    Messages
    413
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Février 2008
    Messages : 413
    Par défaut
    Re, je reviens vite fait sur ce que disait Raptor70:
    Reflechi comment se compose tes deux pipelines :
    sans shader : opengl utilise directement la couleur passée par glColor
    avec shader : opengl charge le shader, (pour chaque pixel) recupère la couleur de glColor, assigne les 3 composantes pour la valeur du fragment(pixel),
    decharge le shader.
    Le GPU doit-il vraiment recharger le shader pour chaque pixel? Si oui je comprends la baisse de performances...mais pas pourquoi une telle limite hardware...

    Sinon j'ai trouvé ce post intéressant,
    http://www.gamedev.net/community/for...opic_id=457011
    entre autres ce passage:

    Quote:
    Original post by xxx
    Hmm, another question for those who write shaders, is it possible to write an equivalent shader in GLSL which performs as well as the fixed function pipeline which is used by default when you don't attach any shaders?



    That depends on the graphics card. Older graphics cards have a fixed function pipeline built into the hardware. Running shaders on those cards will immediately make it slower than the fixed function pipeline, no matter how simple the shader is. On newer cards the fixed function pipeline is emulated by using a set of shaders. On those cards you can definitely write specialized shaders that will outperform the fixed function pipeline.

  13. #13
    Expert confirmé
    Avatar de raptor70
    Inscrit en
    Septembre 2005
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Septembre 2005
    Messages : 3 173
    Par défaut
    Citation Envoyé par ShevchenKik Voir le message
    Le GPU doit-il vraiment recharger le shader pour chaque pixel? Si oui je comprends la baisse de performances...mais pas pourquoi une telle limite hardware...
    Heureusement que non, il ne recharge pas le shader pour chaque pixel... par contre il effectue les opérations inclues pour chaque pixels.. il faut bien pensé que ce sont des programmes, à l'image d'un simple exe, avec des instruction assembleur derrière .... Les vieux GPU étaient limité à 8 ou 9 instructions par shader... donc ca va vite .. heureusement, maintenant, ils supportent beaucoup mieux.

  14. #14
    Membre Expert

    Profil pro
    Programmeur
    Inscrit en
    Août 2002
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Programmeur

    Informations forums :
    Inscription : Août 2002
    Messages : 1 091
    Par défaut
    L'existence de deux pipelines simultanes l' un simulant le texture stage state et l'autre les shaders est partiellement faux. Les shaders et le fixed pipe s'executent sur le meme hardware.

    Maintenant il faut comprendre quelques nuances sur les geforce fx. La puce qui les equipe dispose de deux stages dans son pipeline de shaders, l'un des stages est le texture stage et l'autre le combiner stage. Cette hierarchie est heritee des cartes precedentes (geforce 1-2-3-4) mais la geforce fx a apporte une plus grande programmabilite : le texture stage supporte desormais toutes sortes d'instructions et en plus grand nombre et le combiner stage peut potentiellement avoir plus de "sous-stages" que celui des cartes precedentes.

    Pourquoi les deux stages ? elles n'ont pas la meme precision, meme nombre d'instructions etc. En gros le combiner stage, chaque sous niveau permet de faire des operations precablees par l'envoi d'un ou plusieurs dwords de controle (extension register combiner sous opengl) et est limite a une precision de 12 bits signes ([-2,2] avec 8 bits consacre a l'intervalle [0,1]). En echange le cout en transistor est reduit et l'utilisation des VLIW (mots d'instructions tres longs) permet de caser un maximum d'operations par cycle d'horloge au detriment de la flexibilite. Les shaders de la geforce 3/4 s'effectuaient sur ce stage a l'exception des instructions de texture.

    Le texture stage c'est le contraire il travaille sur deux types de registres (half et full) qui sont en grand nombre theoriquement mais limite par la taille d'une memoire partagee entre les quads. Pour fonctionner a pleine vitesse (toutes unites actives) il faut donc que pas plus de deux registres vectoriels fulls soient utilises en meme temps (ou quatre registres vectoriels half, contenant chacun 4 half float r,g,b,a).

    L'un des problemes que pose GLSL est la virtualisation poussee, ainsi que l'absence de precision sur les variables ce qui fait que du temps de la geforce FX, Nvidia recommendait d'utiliser les extensions maisons (nv fragment programs sous OpenGL)

    Bien entendu sur ton programme simple difficile de dire si le shader est effectivement le goulot d'etranglement (essaie de monter et baisser la resolution), mais de maniere generale l'utilisation de GLSL entrainera de mauvaises performance sur geforce FX (mais beaucoup moins sur les cartes plus recentes).

    LeGreg

    Mon site web | Mon blog | Mes photos | Groupe USA
    > BONJOUR, JE SUIS NOUVEAU SUR CE FORUM
    > presse la touche caps lock, stp
    > OH.. MERCI C EST BEAUCOUP PLUS FACILE COMME CA

Discussions similaires

  1. Appliquer un shader sur un objet 3d simple
    Par n2engineer5 dans le forum API graphiques
    Réponses: 2
    Dernier message: 07/02/2012, 10h40
  2. [Débutant] Question simple sur un fragment shader
    Par coyotte507 dans le forum OpenGL
    Réponses: 3
    Dernier message: 22/09/2011, 21h33
  3. Problème de perfs après simple migration en .Net 2.0
    Par Ideal_Du_Gazeau dans le forum C#
    Réponses: 0
    Dernier message: 23/02/2010, 19h29
  4. Croisement 2 grosses tables -> perfs en chute libre
    Par Alien64 dans le forum PL/SQL
    Réponses: 15
    Dernier message: 08/08/2008, 17h22
  5. Appel d'un pixel shader "simple"
    Par alt3 dans le forum DirectX
    Réponses: 12
    Dernier message: 01/08/2007, 18h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo