developer denoiser cuda raytracing

denoiser - raytracing con CUDA



developer nvidia zone (4)

Actualmente estoy implementando un raytracer. Debido a que el trazado de rayos es extremadamente pesado en el cálculo y dado que de todos modos voy a buscar en la programación de CUDA, me preguntaba si alguien tiene alguna experiencia con la combinación de los dos. Realmente no puedo decir si los modelos computacionales coinciden y me gustaría saber qué esperar. Me da la impresión de que no es exactamente una combinación hecha en el cielo, pero un aumento de velocidad decente sería mejor que nada.


Ciertamente se puede hacer, se ha hecho y es un tema candente actualmente entre los gurús del trazado de rayos y Cuda. Comenzaría por leer http://www.nvidia.com/object/cuda_home.html

Pero es básicamente un problema de investigación. Las personas que lo están haciendo bien obtienen papeles de investigación revisados ​​por pares. Pero bien en este punto, todavía significa que los mejores resultados de GPU / Cuda son aproximadamente competitivos con las mejores soluciones de su clase en CPU / multi-core / SSE. Así que creo que es un poco pronto para suponer que el uso de Cuda va a acelerar un rastreador de rayos. El problema es que aunque el trazado de rayos es "embarazosamente paralelo" (como dicen), no es el tipo de problema de "tamaño fijo de entrada y salida" que se relaciona directamente con las GPU: quieres árboles, pilas, estructuras de datos dinámicas, etc. . Se puede hacer con Cuda / GPU, pero es complicado.

Su pregunta no era clara acerca de su nivel de experiencia o los objetivos de su proyecto. Si este es tu primer rastreador de rayos y solo estás tratando de aprender, evitaría a Cuda; te llevará 10 veces más desarrollarlo y es probable que no obtengas una buena velocidad. Si usted es un programador de Cuda con experiencia moderada y está buscando un proyecto desafiante y el trazado de rayos es algo divertido de aprender, por supuesto, intente hacerlo en Cuda. Si estás haciendo una aplicación comercial y estás buscando obtener una ventaja competitiva de velocidad, bueno, es probable que sea una mierda en este punto ... podrías obtener una ventaja en el rendimiento, pero a expensas de un desarrollo más difícil y dependencia de un hardware particular.

Vuelva a consultar en un año, la respuesta puede ser diferente después de otra generación o dos de velocidad de la GPU, el desarrollo del compilador de Cuda y la experiencia de la comunidad de investigación.


Una cosa de la que hay que tener cuidado en CUDA es que el flujo de control divergente en el código de su kernel absolutamente mata el rendimiento, debido a la estructura del hardware de la GPU subyacente. Las GPU suelen tener cargas de trabajo masivamente paralelas con flujo de control altamente coherente (es decir, tienes un par de millones de píxeles, cada uno de los cuales (o al menos grandes franjas) será operado por el mismo programa de sombreado, incluso tomando el mismo dirección a través de todas las ramas. Esto les permite realizar algunas optimizaciones de hardware, como tener un solo caché de instrucciones, unidad de recuperación y lógica de decodificación para cada grupo de 32 subprocesos. En el caso ideal, que es común en los gráficos, pueden transmitir la misma instrucción para todos los 32 conjuntos de unidades de ejecución en el mismo ciclo (esto se conoce como SIMD, o Single-Instruction Multiple-Data). Pueden emular MIMD (Multiple-Instruction) y SPMD (Single-Program), pero cuando los hilos dentro de un Streaming Multiprocessor (SM) diverge (toma diferentes rutas de código de una bifurcación), la lógica de problemas realmente cambia entre cada ruta de código ciclo por ciclo. Se puede imaginar que, en el peor de los casos, donde todos los hilos están en caminos separados, su la utilización del hardware se redujo en un factor de 32, eliminando de manera efectiva cualquier beneficio que pudieras tener si ejecutaras una GPU sobre una CPU, particularmente considerando la sobrecarga asociada con coordinar el conjunto de datos desde la CPU, sobre PCIe, a la GPU.

Dicho esto, ray-tracing, mientras que data-parallel en cierto sentido, tiene un flujo de control ampliamente divergente incluso para escenas modestamente complejas. Incluso si logras mapear un grupo de rayos espaciados estrechamente que lanzas uno al lado del otro en el mismo SM, la localidad de datos e instrucción que tienes para el rebote inicial no se mantendrá por mucho tiempo. Por ejemplo, imagina los 32 rayos altamente coherentes que rebota en una esfera. Todos ellos irán en direcciones bastante diferentes después de este rebote, y probablemente golpearán objetos hechos de diferentes materiales, con diferentes condiciones de iluminación, y así sucesivamente. Cada material y conjunto de condiciones de iluminación, oclusión, etc. tiene su propia secuencia de instrucciones asociada (para calcular la refracción, reflexión, absorción, etc.), por lo que resulta bastante difícil ejecutar la misma secuencia de instrucciones incluso en una fracción significativa. de los hilos en un SM. Este problema, con el estado del arte actual en el código de trazado de rayos, reduce la utilización de su GPU por un factor de 16-32, lo que puede hacer que el rendimiento sea inaceptable para su aplicación, especialmente si es en tiempo real (por ejemplo, un juego). Todavía podría ser superior a una CPU para, por ejemplo, una granja de renderizado.

Existe una clase emergente de aceleradores MIMD o SPMD que se están estudiando ahora en la comunidad de investigación. Consideraría estas como plataformas lógicas para el software, trazado de rayos en tiempo real.

Si está interesado en los algoritmos involucrados y los asigna al código, consulte POVRay. También busque en el mapeo de fotones, es una técnica interesante que incluso va un paso más cerca de representar la realidad física que el raytracing.