Pregunta

Generamos gráficos para grandes conjuntos de datos. Estamos hablando de 4096 muestras por segundo y 10 minutos por gráfico. Un cálculo simple hace para 4096 * 60 * 10 = 2457600 muestras por linegrafo. Cada muestra es una FP doble de precisión (8 bytes). Además, representamos varios linegrafos en una pantalla, hasta aproximadamente cien. Esto hace que rendericemos unos 25M de muestras en una sola pantalla. Usando el sentido común y trucos simples, podemos obtener este rendimiento del código usando la CPU dibujando esto en un lienzo 2D. Performant, es decir, los tiempos de renderización caen por debajo de un minuto. Como se trata de datos científicos, no podemos omitir ninguna muestra. En serio, esto no es una opción. Ni siquiera empieces a pensar en ello.

Naturalmente, queremos mejorar los tiempos de renderizado utilizando todas las técnicas disponibles. El multinúcleo, la pre-renderización, el almacenamiento en caché son bastante interesantes, pero no lo corte. Queremos una representación de 30FPS con estos conjuntos de datos como mínimo, se prefiere 60FPS. Ahora este es un objetivo ambicioso.

Una forma natural de descargar la representación gráfica es utilizar la GPU del sistema. Las GPU están diseñadas para trabajar con grandes conjuntos de datos y procesarlos en paralelo. Algunas pruebas simples de HelloWorld nos mostraron una diferencia de día y de noche en la velocidad de representación, utilizando la GPU.

Ahora el problema es: las API de GPU como OpenGL, DirectX y XNA están diseñadas para escenas en 3D en mente. Por lo tanto, usarlos para renderizar linegrafos 2D es posible, pero no ideal. En la prueba de conceptos que desarrollamos, encontramos que necesitamos transformar el mundo 2D en un mundo 3D. De repente tenemos que trabajar con un sistema de coordenadas XYZ con polígonos, vértices y más de la bondad. Eso está lejos de ser ideal desde una perspectiva de desarrollo. El código se vuelve ilegible, el mantenimiento es una pesadilla y surgen más problemas.

¿Cuál sería tu sugerencia o idea para esto en 3D? ¿Es la única forma de hacer esto para convertir realmente los dos sistemas (coordenadas 2D frente a coordenadas 3D y entidades)? ¿O hay una manera más elegante de lograr esto?

: ¿Por qué es útil representar múltiples muestras en un píxel? Ya que representa mejor el conjunto de datos. Digamos que en un píxel tiene los valores 2, 5 y 8. Debido a un algoritmo de omisión de muestra, solo se dibuja el 5. La línea solo iría a 5, y no a 8, por lo tanto, los datos están distorsionados. También podría argumentar lo contrario, pero el hecho es que el primer argumento cuenta para los conjuntos de datos con los que trabajamos. Esta es exactamente la razón por la que no podemos omitir muestras.

¿Fue útil?

Solución

Un conjunto de herramientas para visualización científica muy popular es VTK , y creo que se adapta a sus necesidades:

  1. Es una API de alto nivel, por lo que no tendrá que usar OpenGL (VTK se basa en OpenGL). Hay interfaces para C ++, Python, Java y Tcl. Creo que esto mantendría su base de código bastante limpia.

  2. Puede importar todo tipo de conjuntos de datos a VTK (hay toneladas de ejemplos desde imágenes médicas hasta datos financieros).

  3. VTK es bastante rápido, y puede distribuir las tuberías de gráficos VTK en varias máquinas si desea realizar visualizaciones muy grandes.

  4. En cuanto a:

      

    Esto hace que rendericemos cerca de 25M muestras en una sola pantalla.

         

    [...]

         

    Como se trata de datos científicos, no podemos omitir ninguna muestra. En serio, esto no es una opción. Ni siquiera empieces a pensar en ello.

Puede representar grandes conjuntos de datos en VTK por muestreo y utilizando modelos LOD. Es decir, tendrías un modelo en el que verías una versión de baja resolución desde lejos, pero si acercas la imagen verás una versión de mayor resolución. Así es como se realiza una gran cantidad de procesamiento de grandes conjuntos de datos.

No es necesario que elimines puntos de tu conjunto de datos real, pero seguramente puedes refinarlo gradualmente cuando el usuario hace zoom. No te conviene representar 25 millones de puntos en una sola pantalla cuando el usuario no puede hacerlo. Procesar todos esos datos. Le recomendaría que eche un vistazo tanto a la biblioteca VTK como a la guía del usuario de VTK, ya que hay información inestimable sobre formas de visualizar grandes conjuntos de datos.

Otros consejos

Me gustaría comentar sobre su afirmación de que no puede omitir muestras, en la parte posterior de la respuesta de tgamblin.

Debería pensar que los datos que está dibujando en la pantalla son un problema de muestreo. Está hablando de 2,4 millones de puntos de datos, y está tratando de dibujar eso en una pantalla que solo tiene unos pocos miles de puntos (al menos supongo que sí, ya que está preocupado por las tasas de actualización de 30 fps)

Eso significa que, por cada píxel en el eje x, estás representando en el orden de 1000 puntos que no necesitas. Incluso si sigue el camino de la utilización de su gpu (p. Ej., Mediante el uso de opengl), sigue siendo una gran cantidad de trabajo que el gpu debe hacer para las líneas que no serán visibles.

Una técnica que he usado para presentar datos de muestra es generar un conjunto de datos que es un subconjunto de todo el conjunto, solo para renderizar. Para un píxel dado en el eje x (es decir, una coordenada de pantalla del eje x dada), debe representar un absoluto máximo de 4 puntos, que es el mínimo y, el máximo y, el extremo izquierdo y el extremo derecho. . Eso representará toda la información que puede ser útil. Aún puedes ver los mínimos y los máximos, y conservas la relación con los píxeles vecinos.

Teniendo esto en cuenta, puedes calcular la cantidad de muestras que caerán en el mismo píxel en el eje x (imagínatelas como datos & bursátiles " bandejas "). Dentro de una ubicación determinada, puede determinar las muestras particulares para máximos, mínimos, etc.

Para reiterar, este es solo un subconjunto que se usa para la visualización, y solo es apropiado hasta que los parámetros de visualización cambien. p.ej. Si el usuario desplaza el gráfico o hace zoom, debe volver a calcular el subconjunto de procesamiento.

Puede hacer esto si está utilizando opengl, pero como opengl usa un sistema de coordenadas normalizado (y está interesado en las coordenadas de la pantalla del mundo real), tendrá que trabajar un poco más para determinar con precisión sus contenedores de datos. Esto será más fácil sin usar opengl, pero luego no obtendrá todos los beneficios de su hardware de gráficos.

Realmente no tienes que preocuparte por el eje Z si no quieres. En OpenGL (por ejemplo), puedes especificar vértices XY (con Z implícito = 0), girar el zbuffer, usar una matriz de proyección no proyectiva y, por supuesto, estás en 2D.

Mark Bessey lo mencionó, es posible que te falten los píxeles para mostrar el gráfico. Pero dadas tus explicaciones, asumo que sabes lo que estás haciendo.

OpenGL tiene un modo ortogonal que tiene una coordenada z dentro (0; 1). No hay una proyección en perspectiva, los polígonos que dibuje serán planos al área de recorte de pantalla.

DirectX tendrá similares. En OpenGL, se llama gluOrtho2d ().

OpenGL se complace en generar 2D si configura la proyección para que sea Ortho (no z). También deberías diezmar tus datos. Renderizar el mismo píxel 1000 veces es un desperdicio de GPU. Pase su tiempo por adelantado con un decimador multi-hilo performat. Asegúrate de destruir matrices grandes en la GPU usando matrices de vértices u objetos de búfer de vértice (claramente soy un tipo de chico de OpenGL)

  

Esto hace que procesemos aproximadamente 25M muestras en una sola pantalla.

No, no, no a menos que tengas una pantalla realmente muy grande . Dado que la resolución de la pantalla es probablemente de 1.000 a 2.000 píxeles de ancho, realmente debería considerar diezmar los datos antes de graficarlos. Graficar cien líneas a 1,000 puntos por línea probablemente no será un gran problema, en lo que respecta al rendimiento.

Si su código se vuelve ilegible porque está lidiando con las cosas 3D directamente, necesita escribir una capa de adaptador delgada que encapsule todas las cosas 3D OpenGL, y tome datos 2D en una forma conveniente para su aplicación.

Perdóneme si me he perdido algo y estoy predicando el diseño básico orientado a objetos al coro. Sólo digo ...

  

No es necesario que elimines puntos de tu conjunto de datos real, pero seguramente puedes refinarlo gradualmente cuando el usuario hace zoom. No te conviene representar 25 millones de puntos en una sola pantalla cuando el usuario no puede hacerlo. Procesar todos esos datos. Le recomendaría que eche un vistazo tanto a la biblioteca VTK como a la guía del usuario de VTK, ya que hay información inestimable sobre formas de visualizar grandes conjuntos de datos.

Muchas gracias. Esto es exactamente lo que estaba buscando. Parece que VTK usa hardware para descargar este tipo de renderización, también. Por cierto, supongo que te refieres a valioso ;). Segundo, el usuario obtiene información del ejemplo que di. Sin embargo, no es realmente conciso, el resumen de los datos puede ser oro puro para el científico. No se trata de procesar todos los datos para el usuario, se trata de obtener información valiosa de la representación. Los usuarios parecen hacer esto, incluso en la representación muy 'alejada' del conjunto de datos.

¿Alguna sugerencia más?

Quería señalar que además de usar VTK directamente, hay otros dos productos creados en VTK que pueden ser de su interés.

1) ParaView (paraview.org) es una interfaz de usuario construida sobre VTK que hace que los productos de visualización científica sean mucho más fáciles. Puede representar todos los datos que desee siempre que tenga el hardware para manejarlos y es compatible con MPI para varios procesadores / núcleos / clústeres. Es extensible a través de complementos creados por el usuario y utiliza herramientas automatizadas para la creación y compilación de proyectos.

2) ParaViewGeo (paraviewgeo.mirarco.org) es un derivado de exploración geológica y minera de ParaView producido por la compañía para la que trabajo. Tiene soporte incorporado para leer formatos de archivos que ParaView no, como Gocad, Datamine, Geosoft, SGems y otros. Y lo que es más importante, a menudo trabajamos con otros grupos que tienen interés en la información científica con un entregable lazos a la minería, como nuestro trabajo reciente con un grupo que realiza modelado de elementos finitos / discretos. Podría valer la pena echarle un vistazo.

En ambos casos (PV y PVG) sus datos se consideran separados de su vista de esos datos, y como tal, nunca se procesarán " " todos sus datos (ya que probablemente no tendría un monitor lo suficientemente grande para hacerlo), pero tenga la seguridad de que todos " estarán allí " procesado desde su conjunto de datos como esperaba. Si ejecuta filtros adicionales en sus datos, solo se visualizará " " " pero los filtros se calcularán en TODOS tus datos, que aunque no todos sean visibles a la vez, todos estarán en la memoria.

Si estás buscando números, hoy calculé tres cuadrículas regulares de 8 millones de células en PVG. Uno contenía una propiedad vectorial de 7 tuplas (7x8 millones de valores dobles), los otros dos contenían una propiedad escalar (1x8 millones de valores dobles cada uno) para un total de 72 millones de valores dobles en la memoria. Creo que la huella de la memoria estaba cerca de los 500 MB, pero también tenía un conjunto de 400,000 puntos donde cada punto tenía una propiedad vectorial de 7 tuple y también algunos otros datos misceláneos disponibles.

No estoy seguro de si esto es útil, pero ¿podrías usar el tiempo como una dimensión? es decir, un cuadro es una z? Eso podría aclarar las cosas, tal vez? Entonces, ¿quizás podría aplicar efectivamente deltas para construir (es decir, en el eje z) la imagen?

  

No, no, no a menos que tengas una pantalla realmente grande. Dado que la resolución de la pantalla es probablemente de 1.000 a 2.000 píxeles de ancho, realmente debería considerar diezmar los datos antes de graficarlos. Graficar cien líneas a 1,000 puntos por línea probablemente no será un gran problema, en lo que respecta al rendimiento.

En primer lugar, no podemos omitir ninguna muestra al renderizar. Esto es imposible. Esto significaría que la representación no es precisa para los datos en los que se basa el gráfico. Esto realmente es un área prohibida. Período.

En segundo lugar, estamos procesando todas las muestras. Puede ser que múltiples muestras terminen en el mismo píxel. Pero aún así, lo estamos haciendo. Los datos de muestra se convierten en la pantalla. Por lo tanto, se representa. Uno puede dudar de la utilidad de estos datos visualizados, por lo que los científicos (nuestros clientes) exigen que lo hagamos de esta manera. Y tienen un buen punto, IMHO.

Envuelva la biblioteca en una biblioteca 2D más suave y agradable con la Z y las rotaciones establecidas en 0.

-Adam

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top