Comentario Original:

Segun Nvidia los RT core si atraviesan/recorren el BVH, el Hit se devuelve a los Shaders:
https://devblogs.nvidia.com/nvidia-turing-architecture-in-depth/

Si, pero no… es complejo de explicar pero lo intentaré.

El motivo por el cual las GPUs se llevan tan mal con los arboles en general es porque cada nodos tiene un puntero al nodo inferior. ¿Problema? Las operaciones de memoria son extremadamente leeeeeeeeentaaaaaas en una GPU dado que tu tienes decenas de núcleos buscando datos al mismo tiempo y creando una enorme contención, por eso los shaders trabajan con lo datos en su registros. Si quieres realizar un arbol BVH para una GPU convencional necesitas almacenar los datos en un formato que no utilice punteros para que la GPU lo pueda recorrer más fácilmente.

El problema es que los RT Core están dentro de cada SM, conectados a la cache L1 de datos como la unidad de texturas… curiosamente esta es la única parte del SM que tiene la capacidad de ir explorando toda la jerarquia de memoria con tal de obtener los datos de cara a poder captar texturas desde la RAM externa. ¿Cual es la mejor manera? Pues codificando el arbol BVH como si fuese una textura.

Aquí explican muy bien el problema:

Una de las partes más complicadas de implementar un BVH para el trazado de rayos en la GPU es cómo almacenar la estructura BVH y los datos del nodo BVH en un formato amigable parala GPU. Los trazadores de rayos de la CPU almacenan un BVH como una estructura jerárquica que comienza con el nodo raíz, que contiene punteros a sus nodos secundarios (en el caso de un nodo interno) o punteros a triángulos (en el caso de un nodo hoja). Como un BVH se construye recursivamente, los nodos secundarios a su vez contienen punteros a sus propios nodos secundarios y esto continúa hasta que se alcanzan los nodos hoja. Este proceso involucra muchos punteros que pueden apuntar a ubicaciones dispersas en la memoria, un escenario que no es ideal para la GPU.

A las GPU les gustan las estructuras de datos coherentes y alineadas en memoria, como las matrices indexables que evitan el uso de demasiados punteros. En este tutorial, los datos de BVH (como nodos, datos de triángulos, índices de triángulos, datos de intersección calculados previamente) se almacenan en matrices unidimensionales planas (almacenando elementos en profundidad de primer orden atravesando recursivamente el BVH), que se pueden digerir fácilmente por CUDA y se almacenan en la GPU en memoria global o memoria de textura en forma de texturas CUDA (hardware en caché). El BVH en este tutorial está utilizando la memoria de textura CUDA, ya que la memoria global en las GPU más antiguas no está en caché (a diferencia de la memoria de textura). Sin embargo, desde la introducción de Fermi, la memoria global también se almacena en caché y la diferencia de rendimiento cuando se usa uno u otro apenas se nota.

Las unidades de texturas pueden hacer operaciones de memoria mucho más rápidamente que los shaders mismos (menos ciclos para captar un dato). Por eso en computación se utilizan pese a que no se utiliza en teoría el filtrado de texturas, porque son excelentes captadores de datos, pero especialmente el mecanismo de captación de datos no es que forme parte de las TMU sino del entramado de la cache de datos de cada SM/CU… De ahí a que el RT Core esta donde esta.

En el caso de AMD estará integrado en la misma unidad de texturas por motivos obvios, la velocidad a la hora de captar los datos de la unidad de texturas en comparación con los shaders.

Parte de la velocidad de aceleración viene por eso, cuando cargamos el trabajo en los shaders estos para recorrer la estructura de datos incluso si esta almacenada en formato textura, si prescindimos de las unidades de texturas pues…

Ahora bien, el arbol BVH se ha de reconstruir en cada fotograma… ¿Quien o que lo hace? Este se construye teniendo en cuenta la información de la geometría de cada fotograma y ordenandola pero en una GPU que no es un Tile Renderer la información de la geometría se descarta durante el rasterizado. Es por ello que aparieron formas de ordenarla como es la voxelización y la generación de estructuras de datos como los Octree pero eso es sumamente leeentooo para el juego a tiempo real.

Basicamente hay algo que tiene que ver con el llamado Tile Caching y que permite todo esto.

No es que almacenemos la geometría en la cache L2, lo que almacenamos en la cache L2 son los punteros a la geometría. Esto lo hace la GPU automáticamente e internamente almacena un mapa de la geometría que la propia GPU puede entender. Este mapa son una serie de punteros a la geometría o conjunto de goemetría que se encuentran en una posición concreta, Pero claro, leer este mapa desde los shaders es sumamente leeento y de nuevo estamos en lo que os he comentado antes.

Es decir, el BVH que requiere la posición de los objetos en escena…

Es creado antes de la fase de rasterizado, justo en el momento en que el pipeline de geometría puede enviar datos a memoria…

Esto es controlado por el driver y dicho mapa de memoria con los punteros a la geometria es enviado a la CPU para que lo ordene y cree el BVH a partir de esos datos para darselos masticados a la GPU. La geometria ya la hemos descartado pero nos nos importa la información de la misma sino el posicionamiento de la misma que es lo que almacena el BVH que tenemos como una textura

Todo esto se hace de manera transparente a través del driver, la construcción del BVH completo en forma de textura. ¿Y como accedes a la misma? Pues por los mismos mecanismos utilizados que para el Virtual Texturing… Donde el atlas sería el arbol BVH convertido a textura y podríamos acceder a los nodos seleccionando cada uno de ellos.

Para implementar un arbol jerarquico en una GPU, necesitamos definir como almacenar dicha estructura en una memoria de texturas y como la GPU puede acceder a la misma. La implementación tradicional es implementar el arbol haciendo que cada nodo tenga punteros a memoria para irlos enlazando. Cada nodo interno tiene punteros a sus hijos en el arbol hasta el final del mismo donde las hojas del arbol solo contienen datos. Pero como se lleva mal con una GPU lo que hacemos es convertir los punteros en indices dentro de una textura. Simplemente necesitamos almacenar los datos del BVH en un Quadtree de tal manera que se lleve bien con el formato de texturas.

El problema del BVH como textura es que es un parche a las limitaciones de la GPU en estos momentos y no van a cambiar esas limitaciones… ¿Cual es la solución para mejorar el rendiminto entonces? Pues colocar una unidad que pueda construir el atlas de texturas con los datos del BVH sin necesidad de tener que depender de la CPU para ello.

Esto es todo, como siempre tenéis el Discord y los comentarios de la misma entrada para comentar el contenido de la misma.