¿Acceso óptimo a la memoria cuando se usan tablas de búsqueda en GPU?

9

Estoy explorando algoritmos de isosuperficie en GPU para un proyecto de licenciatura (concentrándome específicamente en datos voxel de entrada / salida binarios en lugar de campos de valor real). Así que tengo una implementación de CPU de viejos cubos de marcha en funcionamiento en OpenFrameworks, y ahora en la etapa de tratar de portarlo a los sombreadores de cómputo GLSL, y considerando los escollos antes de sumergirme. Solo he escrito sombreadores vert y frag. antes, así que todo es nuevo para mí.

Mi primer problema es cómo usar eficientemente una tabla de búsqueda en docenas o cientos de hilos en un grupo de trabajo. Entiendo que una GPU tiene diferentes tipos de memoria para diferentes tareas, pero no estoy completamente seguro de cómo funciona cada uno o qué tipo usar.

La tabla de copia clásica de Paul Bourke es una matriz de 256 * 16, por lo que si se usa un tipo de byte escalar, presumiblemente se puede empaquetar en una textura de 4 kb o SSBO.

La pregunta es, ¿cómo evitar que los diferentes hilos se tropiecen? Muchos cubos en cada grupo de trabajo pueden tener la misma configuración y, por lo tanto, intentar acceder a la misma ubicación en el búfer al mismo tiempo. ¿Hay alguna solución u optimización para lidiar con esto?

russ
fuente
Si se trata de una tabla de búsqueda de solo lectura, puede usar un búfer / textura. Puede empaquetarlo en uno de los formatos de textura normales, o puede usar algunas de las características más nuevas de DX11 / OpenGL para tener un formato personalizado. UAV en tierra DX11, o una textura / shader_image_load_store en tierra OpenGL.
RichieSams
Además, eche un vistazo a esta presentación: cvg.ethz.ch/teaching/2011spring/gpgpu/cuda_memory.pdf Es para CUDA, pero debería darle una mejor idea de lo que está sucediendo en el hardware subyacente
RichieSams
No es una respuesta completa, pero cuanto menor sea la cantidad de memoria que use, mejor, ya que será más probable que quepa en cachés y tenga menos errores de caché. Si tiene valores interpolables, como si estuviera horneando puntos en una curva en texturas, puede verificar esto como una forma de obtener tablas de búsqueda de curvas de mayor calidad con menos memoria: blog.demofox.org/2016/02/22/…
Alan Wolfe

Respuestas:

6

El mejor lugar para colocar una tabla de búsqueda para un sombreador de cómputo GPU depende del tamaño de la tabla de búsqueda y la frecuencia / coherencia de acceso. En su caso (mencionó 4kb), la memoria local compartida probablemente sería la mejor (suponiendo que no necesite esta memoria para otros fines en el mismo núcleo). Esta memoria tiene diferentes nombres en diferentes API, pero es la misma cosa arquitectónica y sigue las mismas pautas de rendimiento:

  • CUDA: memoria compartida de grupo de subprocesos
  • DirectCompute: memoria compartida en grupo
  • OpenCL: memoria local
  • Metal: memoria de grupo de hilos
  • OpenGL: memoria compartida

El almacenamiento de la tabla de búsqueda en la memoria global como un búfer de solo lectura puede funcionar igual de bien, dependiendo del tamaño de la caché de la GPU particular en la que se está ejecutando.

Tenga en cuenta que supongo que esta es una tabla de búsqueda de solo lectura. Una tabla de búsqueda de lectura y escritura es una bestia completamente diferente, y no tiene buenas opciones allí.

GroverManheim
fuente
También hay casos en los que un búfer de solo lectura funcionará mejor que almacenar 4 kb de datos de solo lectura en la memoria local compartida. Por ejemplo, almacenarlo en la memoria local puede significar que hay una copia única de sus datos para cada grupo de subprocesos. Si el búfer cabe en la memoria caché, es muy posible que la memoria caché funcione mejor que la memoria local para los patrones de acceso de solo lectura.
John Calsbeek
Gracias por los comentarios chicos. He terminado el proyecto que estaba usando esto por ahora, y terminó apenas usando un r8ui sólo lectura amortiguar la textura, que funcionó bastante bien :)
Russ