openCL光线跟踪和分支内核代码问题

时间:2014-10-03 20:32:04

标签: parallel-processing kernel opencl gpu raytracing

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

但是,在遍历场景时,单个光线可以采用相当多的方向。例如,根据命中对象的材质,光线可以反射或折射。另外,不同的材料需要不同的着色算法。例如,如果一个场景对象需要一个cook-torrance着色器而另一个场景对象需要一个区域各向异性着色器,则需要在内核中调用不同的着色函数。

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

所以"分支"代码结构真的对内核性能造成了很大的阻碍吗?如果是这样,我将如何构建我的代码以解决这个问题呢?

1 个答案:

答案 0 :(得分:2)

第一次传递(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元素的空间,你应该能够投射光线直到depth7或8.所有这些都可以在一个具有适当索引的数组上完成。