parallel-processing - openCL 光线追踪和分支内核代码问题

标签 parallel-processing kernel opencl gpu raytracing

所以我尝试使用 openCL 实现光线/路径跟踪器,它看起来非常简单 - 编写一个跟踪单个光线/像素/等路径的内核,并让它在多个光线上并行执行。

但是,当穿过场景时,单条光线可以采取相当多的方向。例如,根据击中物体的 Material ,光线可以反射或折射。此外,不同的 Material 需要不同的着色算法。例如,如果一个场景对象需要 Cook-torrance 着色器,而另一个场景对象需要 ward 各向异性着色器,则需要在内核中调用不同的着色函数。

根据我所读到的内容,不建议在内核中使用分支代码,因为它会影响性能。但如果我根据每条光线并行化我的代码,这在光线追踪器中似乎是不可避免的。

那么“分支”代码结构真的对内核性能有那么大的阻碍吗?如果是这样,我还能如何构建我的代码来解决这个问题?

最佳答案

第一遍(1M 条光线),无符号字符数组(甚至打包单个位)

   ray 0     ------------------  render end  -------------->   0     \
   ray 1     ------------------  surface    --------------->   1      \
   ray 2     ------------------  surface    --------------->   1        }-- bad for SIMD
   ray 3     ------------------  render end  -------------->   0      /
   ray 4     ------------------  surface    --------------->   1     /
   ...
   ...
   ray 1M    ...

排序(缓存或多路复用以供折射和反射重用) 具有表面类型(存在/不存在)和表面位置(时间一致性)

   ray 1  \
   ray 2   -------------------- all surfaces --------------> 1   good for simd
   ray 4  /
   ray 0  \
   ray x   -------------------- all render end ------------> 0   good for simd
   ray 3  /

   second pass (refraction)  (1M rays)

   ray 1  ..................... refract ...................> cast a new ray  
   ray 2  ..................... refract ...................> cast a new ray
   ray 4  ..................... refract ...................> cast a new ray
   ray 0  .................... no new ray casting .........> offload some other work/draw 
   ray x  .................... no new ray casting .........> offload some other work/draw
   ray 3  .................... no new ray casting .........> offload some other work/draw

   third pass (reflection) (1M rays)

   ray 1  ..................... reflect...................> cast a new ray  
   ray 2  ..................... reflect...................> cast a new ray
   ray 4  ..................... reflect...................> cast a new ray
   ray 0  .................... no new ray casting .........> offload some other work/draw 
   ray x  .................... no new ray casting .........> offload some other work/draw
   ray 3  .................... no new ray casting .........> offload some other work/draw

现在有两组 1M 光线,每次迭代加倍。因此,如果您有 256M 个元素的空间,您应该能够转换光线直到深度 7 或 8。所有这些都可以在具有适当索引的单个数组上完成。

关于parallel-processing - openCL 光线追踪和分支内核代码问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26186383/

相关文章:

c - 使用 vga 将消息打印到屏幕上

assembly - "call"切换到保护模式后

opencl - 使用 OpenCL 或其他 GPGPU 框架在现代 x86 硬件上的 CPU 和 GPU 之间共享数据

c - 在分析 OpenCL 代码时是否还应该测量 clCreateContext() ?

windows - 在 PowerShell 中写入具有多个作业的文件

c - xv6 中的 cgaputc(int c)/uartputc(int c)/constputc(int c) 有什么区别?

java - 最大独立 JVM 进程数

c - opencl 中速度慢的问题

c++ - 在多个节点上运行时 MPI_Reduce() 中的死锁

graphics - 学生项目构想:并行计算