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 :

Latence commandes OpenGL


Sujet :

OpenGL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Mars 2006
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 16
    Par défaut Latence commandes OpenGL
    Salut à tous.
    J'ai un gros problème de latence au niveau de l'affichage en utilisant OpenGL. J'en ai un peu parlé dans un autre post, mais je préfère en créer un nouveau pour voir si quelqu'un peut trouver une explication à mes mesures.
    Ca fait quelques années que j'utilise openGL qui m'a servi à développer un soft de création de scènes en tout genre pour la recherche en neurosciences (ca c'est pour situer la chose). Afin d'être sûr de quand une scène visuelle est présentée à un sujet dont on va étudier son comportement et ses réactions, on doit pouvoir afficher le plus rapidement possible en fonction des interactions du sujet (joystick, souris, capteurs de mouvements, tablette graphique ... enfin tout ce qui peut faire interagir le sujet avec l'environnement).
    Le soft est assez complet et fonctionne plutot bien à part un point sur lequel je me suis toujours cassé les dents : le délai d'affichage.
    Le soft tourne sur un P4 3.6 Ghz, avec une Geforce 2 MX 400, sous WinXP. Certes la carte graphique n'est pas une bete de course, mais j'ai effectué des tests tres simples (affichage d'un simple carré blanc, sans texture, en fonction d'un simple trigger provenant du port parallèle, sur un bit donné (le pin10 au cas ou ...). Ce trigger est envoyé par une machine externe d'acquisition de données temps réel (de type AD Win Pro), qui fonctionne à vitesse tres élevée (quelques dizaine de KHz).
    Le port parallele est "scruté" aussi vite que possible par le PC et, en renvoyant une valeur par le port parallèle vers la machine d'acquistion dès que l'on recoit le trigger, on peut mesurer dans un premier temps le délai de réaction lors de la réception de ce trigger. J'obtiens un délai bien inférieur à la milliseconde. Ceci pour vous expliquer que le trigger est tres vite capté par le pc avec tres peu de variabilité dans le temps (entre 0.01 et 0.08 millisecondes, c'est dire ...) et le tout mesuré par une machine externe précise et non Windows avec un quelconque compteur.
    Bref le top d'affichage est envoyé par la machine temps réel, recu par le pc en quelques dizaines de microsecondes, le carré est précompilé par opengl en une display list (c'est pas tres utile pour un carré blanc mais comme j'ai pleins d'autres objets 2D et 3D, j'en fais diverses display lists dans le soft, mais dans ce cas de test je n'ai qu'un carré blanc en DL) et GLUT swap les buffers.
    Pour tester le délai d'affichage j'ai placé une photo-diode sur l'écran qui envoie donc un signal électrique vers la machine temps réelle dès que le carré est affiché (la montée de la photo-diode est tres tres rapide). On a ainsi le temps de départ du trigger, et le temps réel d'affichage du carré. Et la, je suis perplexe. En synchro verticale avec l'écran à 85Hz, j'obtiens entre 16 et 30 millisecondes de délai (tout en affichant 85 images par secondes, sans en louper une seule, bien synchro avec l'écran, mesuré par FRAPS) donc au moins une image de décalage (11.7 ms pour un balayage complet de l'écran) voire deux selon les cas. Et sans vertical retrace actif, un délai entre 5 et 19 millisecondes.
    En bref, je n'arrive pas a comprendre comment j'arrive à perdre autant de temps en synchro verticale, et comment même arriver à 19ms sans synchro.
    OpenGL fonctionne en architecture client-serveur, donc je veux bien comprendre que les exécutions des différentes commandes ont un certain délai, mais meme en utilisant glFlush, et meme carrément glFinish, rien ne change.
    Je trouve ces délais tres importants et n'arrive pas a les expliquer.
    DirectX serait-il plus adapté à ce que je veux ?
    GLUT poserait-il problème à un quelconque moment ?
    J'ai même essayé de me passer du GlutSwapBuffers en me mettant en simple buffer (et non double), et donc sans synchro verticale et j'obtiens toujours un délai compris entre 6 et 19 ms.
    Peut etre est-ce Windows alors ?

    Ma config et mes libs, pour récapituler :
    P4 3.6Ghz
    Geforce2 MX 400
    WinXP service pack2
    Opengl
    GLUT
    fmod
    glf
    et d'autres trucs ...

    Compilé en mode console, multithreaded DLL avec Visual C++ 7
    Le soft est mis en mode High Priority

    Voila, si quelqu'un a déjà eu l'idée de faire de telles mesures (je sais mon cas est tres particulier et en principe tout le monde s'en fout dans les jeux ou des softs de CAO ou autres) ou et en mesure de m'explquer si cela est normal, faites moi signe.
    encore une fois le soft tourne tres vite, et en mode non vertical retrace, j'obtiens 140 ou plus images par secondes mais la n'est pas le pb, le pb est que les images affichées sont décalées dans le temps d'un ou deux balayages, ce qui est trop important pour moi, et que je ne comprends pas.

    Bonne fin de week end

  2. #2
    Membre éclairé
    Inscrit en
    Juillet 2005
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 80
    Par défaut
    Aussitôt que tu fais ton flush (pas besoin de finish), le GPU va commencer à rendre ton rectangle, ce qui devrait être très rapide. Si tu es double buffer et avec synchro verticale , le moniteur devrait commencer à lire ce que tu viens de rendre au prochain vertical sync, ce qui va augmenter ta latence. En plus le moniteur lit les données lignes par lignes ce qui devrait aussi augmenter ta latence. Si tu sens que tes résultats ne suivent pas cette logique, assure toi que ce n'est pas un problème avec ton moniteur. DirectX ne devrait pas faire mieux qu'OpenGL, je ne crois pas non plus que GLUT soit le problème. Windows n'est pas un OS Realtime, donc tu peux avoir certains glitchs, mais le temps moyen devrait quand même être bon.

  3. #3
    Rédacteur
    Avatar de bafman
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    2 574
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2003
    Messages : 2 574
    Par défaut
    et est ce que tu peut te passer des display list ? car autant ca accelere le rendu quand c'est effectué au demarrage, autant ca le ralentit si c'est effectué à chaque frame...
    * Il est infiniment plus simple de faire rapidement un code qui marche que de faire un code rapide qui marche
    * pour faciliter les recherches, n'oubliez pas de voter pour les réponses pertinentes
    Mes articles

  4. #4
    Membre averti
    Inscrit en
    Mars 2006
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 16
    Par défaut
    J'ai fait de nouveaux tests, et cette fois ci en prenant le code de Nehe, Lesson 2, en code .NET.
    J'ai seulement rajouté le code de inpout32, pour recevoir le trigger par le port parallele.
    En double buffer, et en synchro verticale, la latence est entre 41 et 57 ms, en mode Fullscreen !!
    et cette latence se trouve entre 27 et 39 en mode non Fullscreen.

    La commande de glFlush ne change absolument rien à ces latences.

    Donc dans cet exemple très simple, pas de display lists, juste le code Nehe et le port parallele, qui lui prend au maximum 2 ms (toujours testé par un dispo d'acquisition temps réel externe pour être nickel sur les mesures).

    Donc finalement dans mon soft en GLUT la latence est moins importante, mais toujours trop malheureusement.

  5. #5
    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
    Les commandes envoyées au GPU sont bufférisées quoi qu'il arrive pour maximiser la parallélisation cpu/gpu (pour amortir les différences de temps de rendu cpu entre frames).

    Sous DirectX (mais je pense que c'est similaire sous OpenGL), tu peux avoir l'équivalent de trois frames de rendu in flight (sans compter celle qui est affichée à l'écran).

    Sans synchronisation verticale activée :
    à t, tu affiches la première image sur l'écran, tu commences immédiatement à tracer la deuxième image dans le back buffer et tu commences à accepter les commandes pour tracer la troisième frame.

    Avec synchronisation verticale et triple buffering:
    à t, tu affiches la première image sur l'écran, tu mets la deuxième image qui a fini de tracer dans un tampon temporaire en attente d'être mis à l'écran dès que le vertical blank arrive, tu commences à tracer la troisième image dans le back buffer et tu commences à accepter les commandes sur le CPU pour tracer une quatrième image.

    ton application envoie donc une commande de tracé, elle sera bufferisée et executée au pire une frame plus tard, elle attendra encore au pire (si c'est une des premières commandes) une frame GPU avant que la frame soit finie et prete à afficher sur l'écran et dans le pire des cas elle attendra l'équivalent d'un intervalle de rafraichissement de l'écran avant de commencer à être tracée à l'écran (et n'apparaitra qu'un intervalle plus tard si elle n'affecte que le bas de l'écran).
    Meme si tu arrives à afficher à 60 hz fixe, tu vois que dans le pire des cas tu peux attendre 4 * 1/60 secondes avant de voir l'effet d'une commande sur l'écran. Si ton frame rate est plus bas, tu augmentes d'autant ce délai bien entendu.

    Des solutions ? ne pas utiliser le triple buffering. désactiver vsync (sans vertical sync, à cause du tearing, une commande qui affecte le bas de l'écran peut donc apparaitre avant une commande qui affecte le haut de l'écran) et si ça ne suffit pas, augmenter le framerate en diminuant la charge de travail.
    Enfin il faudra probablement forcer la synchronisation entre le CPU et le GPU, réduire l'avance du CPU sur le GPU en essayant de ne pas trop réduire les performances. Sous OpenGL je crois que tu peux utiliser les fences meme si je n'ai jamais utilisé (ça doit être un peu similaire aux event queries sous DirectX).

    Si seule une partie du rendu est dépendante du temps de réaction essaie de déplacer cette partie très tard dans la frame, tu peux utiliser des fences pour t'assurer que le GPU est prêt à executer cette commande. Cela demande malheureusement de différer toutes les commandes ultérieures puisqu'il n'y a pas de préemption possible.

    Bref le framerate ne fait pas tout dans le contexte d'environnements interactifs.

    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

  6. #6
    Membre averti
    Inscrit en
    Mars 2006
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 16
    Par défaut
    Merci de ta réponse, LeGreg.
    Je n'utilise pas de triple buffering, même si au départ je pensais que ce serait une bonne option.
    Donc je suis en double buffering, synchro avec l'écran. Pas de tearing effect, ce qui serait inacceptable pour nos besoins. Donc synchro verticale activée.
    Je viens d'effectuer un nouveau test en envoyant un trigger sur la machine d'acquisition extern au moment ou je suis censé swapper un buffer contenant un rectangle blanc. Et malheureusement la photodiode ne décèle le rectangle que 30 ms après (en gros) le signal envoyé.
    Mince, je crois que mon problème est insoluble, les commandes graphiques sont donc bien bufferisés et peuvent être exécutées bien plus tard.
    Je vais essayer le fence dont tu parles, mais apres avoir essayé un glFlush et un glFinish sans succès, je commence à désespérer.

    Je suis empli d'une désillusion notable quand aux capacités graphiques de nos machines... je n'aurais jamais pensé à de tels délais d'exécution dans les commandes graphiques. Je vais essayer de changer pour une carte pro, voir si quelque chose change dans l'exécution des commandes OpenGL

  7. #7
    Membre éclairé
    Inscrit en
    Juillet 2005
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 80
    Par défaut
    aussitôt que tu fais glflush les commandes sont envoyés au GPU et rendu dans le back buffer. Le flush et le finish fonctionnent et font ce qu'ils sont supposé faire.

  8. #8
    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
    Citation Envoyé par ceydric
    Et malheureusement la photodiode ne décèle le rectangle que 30 ms après (en gros) le signal envoyé.
    Quelle est la latence de ton système de détection ?
    est-ce que ta scène est complexe en terme de traitement GPU ?
    Est-ce que tu as essayé d'augmenter la fréquence de rafraichissement (100 hz ?).

    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

  9. #9
    Membre averti
    Inscrit en
    Mars 2006
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 16
    Par défaut
    Le système d'acquisition externe marche à 1000 Hz, donc 1ms de latence au max. Mais comme c'est du matériel fait pour différentes mesures très précises en analogique et numérique, on peut le monter à plusieurs dizaines de KHz (80 000 Hz je crois), mais bon je n'ai pas vraiment l'utilité d'aller au dela de 1000 Hz dans ces mesures.
    J'ai créé une scène tres simple, une carré blanc qui s'affiche quand je le lui demande.
    Je ne me suis pas mis à 100 Hz, mon moniteur ne me le permet pas mais quand bien meme, à 85Hz, on affiche 2 ou 3 images plus tard.
    J'ai essayé le glFlush et glFinish, sans succes.
    Je suis tombé sur quelqu'un à force de discuter à droite à gauche qui m'a expliqué un peu que l'architecture des PCs était assez complexe et que les commandes sont bufferisées pour une meilleure efficacité globale. Les drivers des cartes graphiques seraient faits ainsi. Et que probablement je devrais me tourner vers de l'embarqué, car de tels délais sont normaux. C'est pas bête, ca me semble logique.
    Ce serait dommage de devoir en arriver là malgré tout ... mais ca m'expliquerait clairement ce que j'obtiens par les mesures, que je ne peux réfuter. A moins de trouver un truc magique qui traite direct les données sans buffer, mais je suis de plus en plus sceptique, et les OS temps réels sont certainement la pour ca.

  10. #10
    Membre Expert
    Avatar de Sivrît
    Profil pro
    Inscrit en
    Février 2006
    Messages
    953
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2006
    Messages : 953
    Par défaut
    Je suis empli d'une désillusion notable quand aux capacités graphiques de nos machines...
    Question de priorité. Nos systèmes graphiques doivent être optimisés pour le traitement industriel des commandes graphiques (et ils se débrouillent plutôt bien), pas pour afficher un petit quelque chose avec 0 latence. Il n'a jamais été question de garantir le temps de réponse pour le grand publique.

    Il pourrait être intéressant de faire l'expérience sans OpenGL. Peut-être avec de la simple 2D et SDL, ou quelque chose de plus primitif encore pour voir si c'est une couche soft qui introduit le délai. Mais si c'est le drivers (ou le pipeline graphine) c'est mal parti. Un autre truc à mesurer pourrait être le temps que fait attendre la synchro (je crois que l'appel est bloquant pour le programme avec un double buffer).

    Idée comme ça: est-ce que l'écran pourrait aussi avoir son temps de réponse ?

  11. #11
    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
    Citation Envoyé par ceydric
    mais quand bien meme, à 85Hz, on affiche 2 ou 3 images plus tard. J'ai essayé le glFlush et glFinish, sans succes.
    2/3 frames après le retour du glFinish ? je dirais au pire 1/2 frames (si tu traces juste après une synchro verticale il faut attendre la prochaine synchro avant que ça apparaisse à l'écran + le délai pour que le balayage se fasse). Si tu en as plus c'est soit que le driver n'a pas honoré le finish, soit que tu as un système bizarre qui stocke des frames je ne sais où.

    Si tu utilises DDraw tu peux peut-etre faire du single buffering (mais ça n'est plus de la 3d).

    Il y a une époque pas si lointaine, il était possible de tracer en avant du balayage, en agissant très vite on pouvait commencer à tracer dès le signal du vblank et en allant de haut en bas si la charge de travail est assez petite tracer toute la frame pendant la durée du balayage.

    Je crois qu'il y a une certaine console portable qui fait un truc du genre mais dans ce cas, ils controlent le LCD pour faire transiter les pixels physique du LCD à la vitesse du tracé et non l'inverse.
    Bien entendu cela n'est pas du tout possible sur PC .

    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

  12. #12
    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
    Citation Envoyé par ceydric
    Le système d'acquisition externe marche à 1000 Hz, donc 1ms de latence au max.
    Si c'est la fréquence du matériel ce n'est pas une indication de la latence.
    (tout comme ta fréquence de ton affichage ou ton frame rate n'est pas un indicateur de la latence de ton pipeline graphique).

    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

  13. #13
    Membre averti
    Inscrit en
    Mars 2006
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 16
    Par défaut
    Oui, je connais bien ce qui concerne le balayage de l'écran, et c'est normal que si on est synchro sur le signal de vertical retrace, et qu'on arrive avec son buffer à swapper alors que l'écran est en train de balayer pour afficher une image, on attendra la prochaine frame. C'est normal. Mais cela ne me donnerait au pire qu'une frame de decalage, pour les fois ou on se trouve dans le pire des cas, à savoir si le balayage vient a peine de commencer quand on demande de swapper.
    La latence du systeme d'acquisition est vraiment tres faible, entre 0.8 et 10 micro secondes selon le type de connexion. C'est un systeme fait pour fonctionner en autonome et c'est tres solide et fiable de type ADWin Pro (http://www.computeraidedsolutions.com/Products/ADwin/ADwin-Pro.htm)
    Je n'ai aucun doute sur cette machine et en plus toutes mes mesures sont effectuées par cette meme machine.
    J'enregistre les différents signaux dont j'ai besoin, la photo diode a une latence tres faible également, on voit clairement sa montée lorsqu'elle est stimulée, et elle chope haut la main le 85 Hz de l'écran, avec les variations d'intensité de l'écran etc.
    De toutes facons, un simple oscilloscope me permet de voir mes signaux et me donne les memes resultats que mon systeme temps réel.
    Je ne me fie pas au FPS pour savoir si mes images sont bien toutes calculées, mais je fais ca nickel avec ma photodiode. Si j'affiche une image sur deux (une image noire et un carré blan alternés) à 85 Hz, ma photodiode me retourne bien un signal toutes les deux frames (toutes les 11.7 ms).
    J'ai essayé en simple buffering aussi, mais le résultat est le même.
    Toutes mes images sont la, mais décalées dans le temps de 2 frames en gros.
    Je viens d'ailleurs de réaliser un test tres simple. J'affiche mon curseur en meme temps que mon objet 3D (donc, le curseur standard de windows et mon rectangle blanc calculé par OpenGL). Verdict sans appel encore une fois, si je donne a mon rectangle la position du curseur, on voit le décalage clairement. Le rectangle suit toujours le curseur avec un petit délai.
    Alors oui, ptet que le glFinish n'est pas pris en compte, mais lorsque je rajoute un compteur (windows cette fois, de type QueryPerformanceCounter etc ... mais je ne garantis rien sur sa précision cette fois...) on observe qu'il passe plus de temps avant de continuer l'exécution du code. Cette fonction me prend bien du temps et est bloquante. Donc il semble bien passer le temps nécessaire pour que le GPU finisse ses calculs. Mais aucune modif, l'image sera affichée 2 frames plus tard.
    Je pense qu'effectivement les cartes sont ainsi faites, avec leurs drivers (j'ai mis les derniers en date, au cas ou, de chez NVidia) tellement compliquées, qu'elles bufferisent forcément, question de parallélisme ou je ne sais quoi, pour traiter les données .
    C'est vrai qu'on fait pas de l'industriel (en principe) avec nos PC et que pour les jeux ca tourne tres bien comme ca, ca n'embete personne (a part moi, mais je fais pas du jeu, c'est pour ca )
    Pour info j'ai essayé sur un autre soft (je cherche si c'est partout pareil, autre PC, autre soft, autre carte ...) en DirectX cette fois et c'est pire. Je ne critique pas DirectX, c'est pas ca, mais je diversifie mes tests. Donc OpenGL ou DirectX personne ne peut faire mieux il semble. Tout semble etre dans le hardware (ou les drivers)

  14. #14
    Membre averti
    Inscrit en
    Mars 2006
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 16
    Par défaut Confirmation ...
    Ouf, je ne suis pas fou ...
    Je viens enfin de tomber sur quelqu'un qui m'a envoyé un lien.
    OpenGL a bien un délai de 2 frames. L'explication n'est pas tres sure étant donné que personne de chez OpenGL n'a jamais parlé de ca semble-t-il.
    Voici le lien, juste pour si ca vous intéresse. Ils ont fait les mêmes tests que moi, avec la meme photodiode

    http://www.visionegg.org/Intro_and_Overview/Synchronization?action=show&redirect=IntroAndOverview%2FSynchronization

    Et ils sont tombés sur le meme constat. Bouh j'en suis encore tout ému.
    Il n'y a donc pas de solution, en tout cas pour l'instant je pense. Tant pis, je vais essayer quelques tests approfondis sous DirectX et si j'ai pas mieux, je continue mon développement. Alors, que cache DirectX maintenant ...

  15. #15
    Membre éclairé
    Inscrit en
    Juillet 2005
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 80
    Par défaut
    C'est certain que si on cherche quelques part quelqu'un qui dit comme nous, on va sûrement trouver, mais je continue de penser que tu te trompes. Avant de sauter trop vite au conclusion, moi à ta place j'irais poser la même question sur beyond3D (en anglais bien sûr)

    http://www.beyond3d.com/

    Il y a de bonnes chances que des développeurs de NVidia au ATI te répondent.

  16. #16
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Ça donne quoi avec une implémentation logicielle d'OpenGL ?

  17. #17
    Membre averti
    Inscrit en
    Mars 2006
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 16
    Par défaut Tout s'explique
    Ca y est, j'ai enfin percé les secrets d'OpenGL ...
    Bon d'acc y'a rien de secret, j'ai simplement compris pourquoi tant de latence. Direct X fonctionne pareil d'ailleurs.
    Pour commencer, il y a bien 2 images de décalage, donc en gros 30 ms de délai.
    Via un petit utilitaire de chez NVidia (NVTray), j'ai pu enlever un buffer du circuit, ce qui m'a fait gagner une image, mais fait apparaitre quelques petits pbs qui m'ont tout expliqué
    En effet, contrairement à ce que beaucoup croient (et moi le premier), il n'y a pas juste un back buffer, et un front buffer (en double buffering avec synchro verticale), mais bien un 3eme buffer servant de tampon. Je ne parle pas de l'option triple buffering que l'on peut utiliser et qui n'a pas la meme raison d'etre. Le pourquoi du comment est simple. Le CPU et le GPU doivent fonctionner de maniere asycnhrone, comme certains me l'avaient suggéré, sans que je ne comprenne vraiment pourquoi ne pas les rendre synchrone. En effet, les commandes OpenGL (et Direct X) prennent du temps au GPU. Et lorsqu'on demande au GPU de lancer des calculs des objets, lumières etc, on enchaine diverses appels de fonction, en général beaucoup. Et si on termine ces appels par un swap de buffer, le GPU n'aura pas fini ses calculs, et donc, en fonctionnant en synchrone, le CPU attendrait pour rien. Et on raterait peut etre une image. Le principe est donc de laisser le GPU faire son boulot, de demander un swap, mais qui sera le swap du buffer deja calculé à la frame précédante. Laissant ainsi le temps au GPU de finir ses calculs (un appel à gl Flush est fait automatiquement par l'appel du swap buffer dans openGL) pour remplir la frame courante qui sera affichée à la frame suivante.
    Je sais pas si tout le monde suit. J'aurais ptet du faire un post à part et mieux détaillé pour expliquer tout ca.
    Bref, voila pourquoi exécuter un glFlush, ou meme un glFinish ne changeait rien aux mesures de latence. Et tout devient donc très logique. Puisqu'ainsi on demande au GPU d'exécuter toutes les commandes, mais qui vont de toutes facons remplir le buffer tampon, et non celui qui va etre echangé avec le front buffer.
    Il y a donc bien un moyen de se passer de ce buffer supplémentaire, avec NVTray (j'ai essayé des fonction C directement dans le code de mon soft censées faire la meme chose, mais bien que le code semble exécuté et que la carte ait accepté de supprimer son buffer supplémentaire, dans la pratique il n'en était rien ...). Mais du coup, les commandes openGL prenant du temps à etre exécutées par le GPU, il faut venir calculer l'image courante plusieurs ms avant de swapper, et peut meme faire rater une image si on n'est pas revenu à temps.

    Enfin voila, merci à tous de m'avoir aidé et proposé des solutions, j'ai bien dû me casser les dents 3 semaines sur ce point mais j'ai enfin fini par tout digérer et comprendre pourquoi avec des cartes graphiques actuelles, memes pro, on atteint un délai de 30 ms entre une commande et le résultat à l'affichage. Bien sûr, la synchro verticale y est pour quelque chose, mais je ne pouvais pas m'en passer, le tearing effect est un vrai pb pour moi.

  18. #18
    Membre éclairé
    Inscrit en
    Juillet 2005
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 80
    Par défaut
    Si tu veux synchroniser ton GPU et ton CPU tu n'as qu'à faire un glFinish après ton swap buffer, le glFinish ne va pas retourner tant que tu n'auras pas reçu ton VSYNC. Peut-être que finalement ton problème est un problème de synchronisation, car nous n'avons pas ce problème de latence sur notre application. De plus je me demande bien où tu as pu trouver cette info sur le buffer de tampon, si ça s'applique au GPU que tu utilises je ne crois pas que ce soit généraliser à tout les GPUs.

  19. #19
    Membre éclairé
    Inscrit en
    Juillet 2005
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 80
    Par défaut
    Plus que j'y pense, plus que je me dis que ton problème est un problème de synchronisation, car en effet si tu ne synchronises jamais ton rendu tu auras 2 frames de latence.

    voici un exemple avec synchro verticale:

    Démarrage:

    -Rendu Frame 0
    -glSwapBuffer 0 -> un finish implicit est effectué, la commande se fera au VSYNC, mais le GPU retourne la main au CPU
    -Rendu Frame 1
    -glSwapBuffer 1 -> un finish implicit est effectué et bloc le cpu, car le premier swapbuffer n'a pas encore été exécuté.

    VSync 0 :
    - le glswapbuffer 0 peut s'exécuter
    - le frame 0 commence à être afficher
    - le glSwapBuffer 1 débloque, car le glswapbuffer 0 a pu s'exécuter, la commande de swapbuffer du frame 1 se fera au prochain VSYNC.
    - Rendu du Frame 2
    - glSwapBuffer 2 -> un finish implicit est effectué et bloc le cpu, car le swapbuffer 1 n'a pas encore été exécuté.

    VSync 1:
    - le glswapbuffer 1 peut s'exécuter
    - le frame 1 commence à être afficher -> nous avons donc ici 2 frames de latence.

  20. #20
    Membre averti
    Inscrit en
    Mars 2006
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 16
    Par défaut
    Salut gybe,
    pour répondre à ton premier post, en fait ca ne dépend pas de mon GPU, mais bien des drivers fournis par tous les fabriquants. Enfin quand je parle de tous, j'ai essayé ATI et NVIDIA. Et j'ai bien trouvé quelques explications (au moins chez NVidia) ou ils parlent de ce, ou ces buffers supplémentaires, en conseillant de ne pas les enlever (on peut même en rajouter si on veut )
    C'est d'ailleurs chez eux que j'ai trouvé l'utilitaire pour supprimer le buffer mis par défaut dans leurs drivers (que tu ne peux enlever par le menu commun de leurs drivers). Car en effet, du coup, on voit bien que par défaut on a 2 frames précalculées (placées en mémoire, enfin disons plutot un back buffer, un tampon et le front buffer) (c'est érit dans leur interface du NVTray). Voici d'ailleurs une breve explication de ce lag, venu tout droit de chez NVidia, car ces buffers doivent être réglés si on veut exécuter une application en SLI avec de meilleures perfs, sinon en principe personne ne s'en rend compte et ne vire ce buffer supplémentaire : http://download.nvidia.com/developer/GPU_Programming_Guide/GPU_Programming_Guide.pdf
    Va voir au 8.5
    Ils parlent de directX, mais ca marche exactement pareil pour OpenGL. Même si le but est d'améliorer le rendement du SLI, le début est une explication générique qui parle de ce lag courant fait par les drivers.
    Et honnêtement je ne m'en serai jamais rendu compte si je n'avais pas fait ces tests avec une photodiode. Comment as-tu testé ce délai pour être sûr de ne pas avoir ces buffers ? En tout cas si tu n'as rien changé aux drivers, tu devrais les avoir, et ils s'averent utiles comme j'ai essayé de l'expliquer dans le post précédent.
    Perso j'ai fait des tests sur une application de réalité virtuelle/jeu vidéos vendue (chère ) dans le commerce et ils n'ont pas échapé à la règle, à leur grand étonnement quand je leur en ai parlé (ils se sont déplacés pour une formation chez nous et on a pu faire des tests)
    MAis cela dit, si tu as viré ce buffer, les images peuvent rester fluides à condition de venir calculer les images le plus tot possible pour avoir le temps de remplir le back buffer et l'afficher en swappant sans buffer supplémentaire. MAis pour mon appli c'est impossible puisque je dois passer beaucoup de temps à sauvegarder toutes sortes de données et passer le moins de temps possible à attendre la synchro CPU/GPU.
    Bon je vais quand même essayer de trouver le meilleur rendement possible voir si je peux me permettre de me passer de ce buffer par défaut (pour gagner une frame) ou pas.

Discussions similaires

  1. SDL-openGL latences temporaires
    Par Erwin dans le forum OpenGL
    Réponses: 11
    Dernier message: 17/01/2007, 14h39
  2. Directx ou opengl
    Par scorpiwolf dans le forum DirectX
    Réponses: 13
    Dernier message: 07/02/2003, 08h29
  3. OpenGL et *.3ds
    Par tintin22 dans le forum OpenGL
    Réponses: 4
    Dernier message: 06/05/2002, 13h51
  4. OpenGL ou DirectX
    Par Nadir dans le forum DirectX
    Réponses: 6
    Dernier message: 02/05/2002, 12h48
  5. Opengl -- Les surfaces
    Par Anonymous dans le forum OpenGL
    Réponses: 2
    Dernier message: 02/05/2002, 10h14

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