Question

Nous générons des graphiques pour d’énormes jeux de données. Nous parlons de 4096 échantillons par seconde et 10 minutes par graphique. Un simple calcul donne 4096 * 60 * 10 = 2457600 échantillons par graphique. Chaque échantillon est un FP de précision double (8 octets). De plus, nous affichons plusieurs graphiques linéaires sur un écran, jusqu’à une centaine. Cela fait que nous rendons environ 25 millions d'échantillons sur un seul écran. En utilisant du bon sens et des astuces simples, nous pouvons obtenir ce code performant en utilisant le CPU pour le dessiner sur une toile 2D. Performant, les temps de rendu sont inférieurs à une minute. Comme il s'agit de données scientifiques, nous ne pouvons omettre aucun échantillon. Sérieusement, ce n'est pas une option. Ne commence même pas à y penser.

Naturellement, nous souhaitons améliorer les temps de rendu en utilisant toutes les techniques disponibles. Multicore, pré-rendu, mise en cache sont tous très intéressants mais ne les coupons pas. Nous voulons un rendu 30FPS avec ces jeux de données au minimum, 60FPS préféré. Nous avons maintenant un objectif ambitieux.

Un moyen naturel de décharger le rendu graphique consiste à utiliser le GPU du système. Les GPU sont conçus pour fonctionner avec d’énormes jeux de données et les traiter parallèlement. Certains tests HelloWorld simples nous ont montré une différence de vitesse de rendu jour et nuit, en utilisant le GPU.

Maintenant, le problème est le suivant: les API GPU telles que OpenGL, DirectX et XNA sont conçues pour les scènes 3D. Ainsi, leur utilisation pour le rendu de graphiques linéaires 2D est possible, mais pas idéale. Dans la preuve de concepts que nous avons développée, nous avons constaté que nous devions transformer le monde 2D en un monde 3D. Nous devons soudainement travailler avec le système de coordonnées XYZ avec des polygones, des sommets et plus encore. C’est loin d’être idéal du point de vue du développement. Le code devient illisible, la maintenance est un cauchemar et plus de problèmes se résument.

Quelle serait votre suggestion ou idée de faire cela en 3D? Est-ce le seul moyen de convertir les deux systèmes (coordonnées 2D par opposition aux coordonnées 3D et entités)? Ou y a-t-il un moyen plus élégant d'y parvenir?

-Pourquoi est-il utile de rendre plusieurs échantillons sur un pixel? Puisqu'il représente le jeu de données mieux. Disons sur un pixel, vous avez les valeurs 2, 5 et 8. En raison de certains algorithmes d'omission d'échantillons, seul le 5 est dessiné. La ligne irait seulement à 5 et non à 8, les données sont donc déformées. Vous pouvez également faire valoir le contraire, mais le fait est que le premier argument compte pour les jeux de données avec lesquels nous travaillons. C’est précisément la raison pour laquelle nous ne pouvons pas omettre d’échantillons.

Était-ce utile?

La solution

La VTK constitue un outil très populaire pour la visualisation scientifique. Elle convient à vos besoins:

  1. C'est une API de haut niveau, vous n'avez donc pas besoin d'utiliser OpenGL (VTK est construit sur OpenGL). Il existe des interfaces pour C ++, Python, Java et Tcl. Je pense que cela garderait votre base de code assez propre.

  2. Vous pouvez importer toutes sortes de jeux de données dans VTK (il existe une multitude d'exemples allant de l'imagerie médicale aux données financières).

  3. VTK est assez rapide et vous pouvez répartir les pipelines graphiques VTK sur plusieurs machines si vous souhaitez effectuer de très grandes visualisations.

  4. Concernant:

      

    Cela rend le rendu d’environ 25 millions d’échantillons sur un seul écran.

         

    [...]

         

    S'agissant de données scientifiques, nous ne pouvons omettre aucun échantillon. Sérieusement, ce n'est pas une option. Ne commence même pas à y penser.

Vous pouvez rendre de grands ensembles de données dans VTK en échantillonnant et en utilisant des modèles LOD. C'est-à-dire que vous auriez un modèle dans lequel vous verrez une version basse résolution de loin, mais si vous zoomez, vous verrez une version plus haute résolution. C’est ainsi qu’un grand nombre de rendus de grands ensembles de données sont effectués.

Vous n'avez pas besoin d'éliminer des points de votre jeu de données réel, mais vous pouvez certainement l'affiner progressivement lorsque l'utilisateur effectue un zoom avant. Il ne sert à rien de rendre 25 millions de points sur un seul écran lorsque l'utilisateur ne peut pas réellement traiter toutes ces données. Je vous recommanderais de consulter à la fois la bibliothèque VTK et le guide de l'utilisateur VTK, car ils contiennent des informations précieuses sur la manière de visualiser de grands ensembles de données.

Autres conseils

Je voudrais commenter votre affirmation selon laquelle vous ne pouvez pas omettre d'échantillons, au verso de la réponse de tgamblin.

Vous devez considérer les données que vous dessinez à l'écran comme un problème d'échantillonnage. Vous parlez de 2,4 millions de points de données et vous essayez de les afficher sur un écran de quelques milliers de points seulement (du moins je suppose que oui, car vous craignez des taux de rafraîchissement de 30 images par seconde)

Cela signifie donc que pour chaque pixel de l’axe des x, vous effectuez un rendu de l’ordre de 1 000 points dont vous n’avez pas besoin. Même si vous utilisez effectivement votre gpu (par exemple, en utilisant opengl), cela représente toujours beaucoup de travail que le gpu doit faire pour les lignes qui ne seront pas visibles.

Une technique que j’ai utilisée pour présenter des exemples de données consiste à générer un ensemble de données qui est un sous-ensemble de l’ensemble, uniquement pour le rendu. Pour un pixel donné sur l'axe x (c.-à-d. Une coordonnée d'écran d'écran d'axe x donnée), vous devez restituer un maximum absolu de 4 points, c'est-à-dire le y minimum, le maximum y, le plus à gauche et le plus à droite. . Cela rendra toutes les informations qui peuvent être rendues utilement. Vous pouvez toujours voir les minima et les maxima et conserver la relation avec les pixels voisins.

En gardant cela à l’esprit, vous pouvez calculer le nombre d’échantillons qui tomberont dans le même pixel sur l’axe des x (considérez-les comme des données "bacs"). Dans un groupe donné, vous pouvez ensuite déterminer les échantillons particuliers pour les maxima, les minima, etc.

Pour réitérer, il ne s’agit que d’un sous-ensemble utilisé pour l’affichage - et n’est approprié que jusqu’à ce que les paramètres d’affichage changent. par exemple. si l'utilisateur fait défiler le graphique ou les zooms, vous devez recalculer le sous-ensemble de rendu.

Vous pouvez le faire si vous utilisez opengl, mais comme il utilise un système de coordonnées normalisé (et que vous vous intéressez aux coordonnées de l'écran dans le monde réel), vous devrez travailler un peu plus fort pour déterminer avec précision vos fichiers de données. Cela sera plus facile sans utiliser opengl, mais vous ne tirerez pas pleinement parti de votre matériel graphique.

Vous n’avez vraiment pas à vous soucier de l’axe Z si vous ne le souhaitez pas. Dans OpenGL (par exemple), vous pouvez spécifier les sommets XY (avec Z implicite = 0), activer le tampon z, insérer une matrice de projection non projective et vous êtes à la 2D.

Mark Bessey l’a mentionné, il se peut que vous n’ayez pas les pixels pour afficher le graphique. Mais compte tenu de vos explications, je suppose que vous savez ce que vous faites.

OpenGL a un mode orthogonal qui a une coordonnée z à l'intérieur (0; 1). Il n’ya pas de projection en perspective, les polygones dessinés seront plans par rapport à la zone de découpage d’écran.

DirectX aura similaire. Sous OpenGL, il s’appelle gluOrtho2d ().

OpenGL est heureux de rendre le rendu 2D si vous configurez la projection comme étant Ortho (pas de z). Aussi, vous devriez décimer vos données. Rendre le même pixel 1000 fois est un gaspillage de GPU. Passez votre temps au départ avec un décimateur performat multi-thread. Assurez-vous d’exploser de grands tableaux au niveau du GPU en utilisant des tableaux de sommets ou des objets de tampon de sommets (clairement, je suis un peu un type OpenGL de type)

  

Cela rend le rendu d'environ 25 millions d'échantillons dans un seul écran.

Non, sauf si vous avez un écran vraiment très grand . Étant donné que la résolution de l'écran est probablement supérieure à 1 000 - 2 000 pixels, vous devez vraiment envisager de décimer les données avant de les représenter graphiquement. Représenter graphiquement une centaine de lignes à 1 000 points par ligne ne sera probablement pas un problème, en termes de performances.

Si votre code devient illisible car vous manipulez directement des éléments 3D, vous devez écrire un adaptateur mince qui encapsule tous les éléments 3D OpenGL et prend les données 2D sous une forme adaptée à votre application.

Pardonnez-moi si j’ai oublié quelque chose et si je prêche une conception de base orientée objet vers la chorale. Juste dire '...

  

Vous n'avez pas besoin d'éliminer des points de votre jeu de données réel, mais vous pouvez certainement l'affiner progressivement lorsque l'utilisateur effectue un zoom avant. Il ne sert à rien de rendre 25 millions de points sur un seul écran lorsque l'utilisateur ne peut pas réellement traiter toutes ces données. Je vous recommanderais de consulter à la fois la bibliothèque VTK et le guide de l'utilisateur VTK, car ils contiennent des informations précieuses sur la manière de visualiser de grands ensembles de données.

Merci beaucoup. Ceci est exactement ce que je cherchais. Il semble que VTK utilise également du matériel pour décharger ce type de rendu. Btw, je suppose que vous voulez dire précieux ;). Deuxièmement, l'utilisateur reçoit des informations sur l'exemple que j'ai donné. Bien que peu concis, l’aperçu des données peut être réellement un pur or pour le scientifique. Il ne s'agit pas de traiter toutes les données pour l'utilisateur, mais de tirer des informations précieuses du rendu. Les utilisateurs semblent le faire, même dans la représentation très "zoomée" de l'ensemble de données.

D'autres suggestions?

Je voulais souligner qu'en plus de l'utilisation directe de VTK, deux autres produits construits sur VTK pourraient vous intéresser.

1) ParaView (paraview.org) est une interface utilisateur construite sur VTK qui facilite grandement les produits de visualisation scientifique. Vous pouvez restituer toutes les données souhaitées, à condition que vous disposiez du matériel nécessaire pour les gérer. Il prend en charge MPI pour plusieurs processeurs / cœurs / clusters. Il est extensible via les plugins créés par l'utilisateur et utilise des outils automatisés pour la construction et la compilation de projets.

2) ParaViewGeo (paraviewgeo.mirarco.org) est un dérivé de la géologie et de l’exploration minière de ParaView, produit par la société pour laquelle je travaille. Il prend en charge de manière intégrée la lecture de formats de fichiers que ParaView ne propose pas, tels que Gocad, Datamine, Geosoft, SGems et d’autres. Plus important encore, nous travaillons souvent avec d'autres groupes qui s'intéressent à la science, avec un résultat livrable lié à l'exploitation minière, comme notre travail récent avec un groupe effectuant la modélisation par éléments finis / discrets. Cela vaut peut-être la peine de vérifier.

Dans les deux cas (PV et PVG), vos données sont considérées comme distinctes de votre vue et, par conséquent, vous ne "rendrez" jamais toutes vos données (car vous n’auriez probablement pas un moniteur assez grand pour le faire), mais soyez assuré que tout sera "là-bas" traité à partir de votre ensemble de données comme prévu. Si vous utilisez des filtres supplémentaires sur vos données, seul ce qui peut être vu sera "rendu". mais les filtres calculeront sur TOUTES vos données, qui, bien qu’elles ne soient pas toutes visibles en même temps, existeront toutes en mémoire.

Si vous cherchez des chiffres, j’ai calculé aujourd’hui trois grilles régulières de 8 millions de cellules en PVG. L'un contenait une propriété vectorielle de 7 tuple (7 x 8 millions de valeurs doubles), les deux autres contenaient chacun une propriété scalaire (1x 8 millions de valeurs doubles chacune) pour un total de 72 millions de valeurs doubles en mémoire. Je crois que l’encombrement de la mémoire avoisinait les 500 Mo, mais j’avais également un ensemble de 400 000 points, chaque point ayant une propriété de vecteur de 7 tuple et quelques autres données diverses disponibles.

Vous n'êtes pas sûr que cela soit utile, mais pourriez-vous utiliser le temps comme dimension? c'est-à-dire qu'un cadre est un z? Cela pourrait rendre les choses plus claires, peut-être? Alors peut-être que vous pourriez effectivement appliquer des deltas pour construire (c'est-à-dire sur l'axe des z) l'image?

  

Non, pas tant que vous n’avez pas un très grand écran. Étant donné que la résolution de l'écran est probablement supérieure à 1 000 - 2 000 pixels, vous devez vraiment envisager de décimer les données avant de les représenter graphiquement. Représenter graphiquement une centaine de lignes à 1 000 points par ligne ne sera probablement pas un problème, en termes de performances.

Tout d’abord, nous ne pouvons pas omettre d’échantillons lors du rendu. C'est impossible. Cela signifierait que le rendu n'est pas précis par rapport aux données sur lesquelles le graphique est basé. C'est vraiment une zone interdite. Période.

Deuxièmement, nous sommes à rendre tous les exemples. Il se peut que plusieurs échantillons finissent sur le même pixel. Mais encore, nous le rendons. Les données de l'échantillon sont converties à l'écran. Ainsi, il est rendu. On peut douter de l’utilité de ces données visualisées, mais les scientifiques (nos clients) exigent qu’ils le fassent de cette façon. Et ils ont un bon point, IMHO.

Emballez la bibliothèque dans une bibliothèque 2D plus douce et plus douce avec le Z et les rotations tous définis à 0.

-Adam

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top