2010-01-10 23 views
7

Estoy escribiendo mi propia biblioteca de gráficos (sí, es tarea :) y uso cuda para hacer todas las representaciones y cálculos rápidamente.Dibujando triángulos con CUDA

Tengo un problema con el dibujo de triángulos rellenos. Lo escribí de tal manera que un proceso dibuja un triángulo. Funciona bastante bien cuando hay muchos triángulos pequeños en la escena, pero rompe totalmente el rendimiento cuando los triángulos son grandes.

Mi idea es hacer dos pases. En primer lugar, solo calcule la pestaña con información sobre líneas de exploración (dibuje de aquí para allá). Esto sería un triángulo por cálculo de proceso como en el algoritmo actual. Y en segundo lugar realmente dibuje las líneas de exploración con más de un proceso por triángulo.

¿Pero será lo suficientemente rápido? Tal vez hay alguna solución mejor?

Respuesta

3

Puede verificar esto blog: Una tubería de representación de software en CUDA. No creo que sea la forma óptima de hacerlo, pero al menos el autor comparte algunas fuentes útiles.

En segundo lugar, lea esto paper: Una arquitectura de representación programable y paralela.Creo que es uno de los trabajos más recientes y también está basado en CUDA.

Si tuviera que hacer esto, me gustaría ir con un gasoducto rasterización de datos en paralelo como en Larrabee (que es TBR) o incluso REYES y adaptarlo a CUDA:

http://www.ddj.com/architect/217200602 http://home.comcast.net/~tom_forsyth/larrabee/Standford%20Forsyth%20Larrabee%202010.zip (ver el segunda parte de la presentación)

http://graphics.stanford.edu/papers/mprast/

0

Sospecho que tiene algunos conceptos erróneos sobre CUDA y cómo usarlos, especialmente porque se refiere a un "proceso" cuando, en la terminología de CUDA, no existe tal cosa.

Para la mayoría de las aplicaciones CUDA, hay dos cosas importantes para obtener un buen rendimiento: optimizar el acceso a la memoria y asegurarse de que cada hilo CUDA activo en una urdimbre realiza la misma operación al mismo tiempo que otros hilos activos en la urdimbre. Ambos suenan como importantes para su aplicación.

Para optimizar su acceso a la memoria, debe asegurarse de que sus lecturas de la memoria global y sus escrituras en la memoria global se combinen. Puede leer más sobre esto en la guía de programación de CUDA, pero esencialmente significa que los hilos adyacentes en una mitad de urdimbre deben leer o escribir en ubicaciones de memoria adyacentes. Además, cada hilo debe leer o escribir 4, 8 o 16 bytes a la vez.

Si su patrón de acceso a la memoria es aleatorio, entonces es posible que deba considerar el uso de la memoria de textura. Cuando necesite referirse a la memoria que ha sido leída por otros hilos en un bloque, entonces debe hacer uso de la memoria compartida.

En su caso, no estoy seguro de cuáles son sus datos de entrada, pero al menos debe asegurarse de que sus escrituras estén unidas. Probablemente tendrá que invertir una cantidad de esfuerzo no trivial para que sus lecturas funcionen de manera eficiente.

Para la segunda parte, recomendaría que cada subproceso CUDA procese un píxel en su imagen de salida. Con esta estrategia, debes tener cuidado con los bucles en tus núcleos que se ejecutarán más o menos dependiendo de los datos por hilo. Cada hilo en sus urdimbres debe realizar la misma cantidad de pasos en el mismo orden. La única excepción a esto es que no existe una penalización de rendimiento real por tener algunos subprocesos en un warp que no realizan ninguna operación mientras que los subprocesos realizan la misma operación juntos.

Por lo tanto, recomendaría tener cada hilo comprobar si su píxel está dentro de un triángulo determinado. Si no, no debería hacer nada. Si lo es, debe calcular el color de salida para ese píxel.

Además, recomiendo leer más acerca de CUDA, ya que parece que estás saltando a las profundidades sin tener una buena comprensión de algunos de los fundamentos básicos.

+1

Lo siento por mi idioma, el inglés no es mi nativo. Entonces, ¿cuál es la terminología adecuada para el procesamiento en tarjetas gráficas? Bueno, creo que entiendo CUDA bastante bien, pero sí, tengo falta de conocimiento en algoritmos paralelos. Mi entrada es un conjunto de vértices en el espacio de recorte, y tuve que dibujar triángulos. Creo que el algoritmo en el que cada píxel debería verificar cada triángulo no sería óptimo. – qba

+0

Evitar que cada píxel se compruebe cada triángulo se puede hacer mediante la partición de triángulos utilizando BVH, KD-Tree o R-Tree. – whatnick

-1

no ser grosero, pero no es esto lo que las tarjetas gráficas están diseñadas para hacer de todos modos? Parece que usar las API estándar de OpenGL y Direct3D tendría más sentido.

¿Por qué no utilizar las API para hacer su representación básica, en lugar de CUDA, que es de un nivel mucho más bajo? Luego, si desea realizar operaciones adicionales que no son compatibles, puede usar CUDA para aplicarlas en la parte superior. O tal vez implementarlos como sombreadores.

+0

Sí, sí de hecho. Pero su objetivo aquí es construir una canalización gráfica de rasterización SIN las API tradicionales. Piense en ello como una prueba de concepto o proyecto de propósito educativo. – Stringer

+0

Sí, su proyecto para mis estudios. Tuvimos que hacer toda la rasterización nosotros mismos. La mayoría de las personas usa CPU, pero decidí usar CUDA. – qba

+0

Hmm, en ese caso, parece un proyecto interesante. Una especie de enfoque hacia atrás, pero interesante de todos modos. – BobMcGee