基本流程:
CUDA基本概念
Figure 1 CUDA Thread Model
当一个kernel被执行时,可以在逻辑上指定具体的Grid,Block来管理thread,Grid和Block可以是1~3维。而在执行中,warp是基本单元,一个warp包含32个thread,同一个warp下的thread以不同的资源执行相同的指令。所以,block中的thread数目最好是32的整数倍。
Figure 2 divergence
因为warp下所有thread都执行同一指令,因此应该尽量避免divergence,保证线程效率。还有latency的处理上,GPU和CPU策略上的不同,CPU类似短跑,提高单个运动员的起跑时间来降低latency,而GPU可以把thread看成拓宽的跑道,每个运动员的起跑时间要比CPU的低,但一次起跑的人数多,进而降低了单位运动员需要的latency。
内存
Figure 3 GPU Memory Model
GPU的内存是可编程的,而CPU的缓存是不可编程的;GPU的线程管理是不可编程的,而CPU的多线程管理(SIMD)是可编程的。
CUDA中有device和host两个概念,前者对应GPU的资源,后者对应CPU的资源。基于CUDA,我们可以封装一个CoreBuffer来负责内存的调度,方便在GPU创建内存,以及GPU和CPU之间资源的互相传递。同时,可以调用cudaMemcpyToSymbol方法保存到__constant__,全局可见,该变量可以是自定义的结构体。
GPU和CPU的传递往往是性能的瓶颈,因此应当尽量减少,为了尽可能的减少传递:
函数
CUDA函数分为三类:
OptiX
我对OptiX用的不多,主要集中在创建BVH和Query这两部分,仅根据自己的使用经验总结。
在使用中,Optix中用于Query的数据和CUDA中用于渲染的数据在内存上是独立的,这样,当我们用OptiX找到hit对应的三角形,通过索引对应到用于渲染的数据。所有材质,纹理等都只是CUDA需要,OptiX不需要。
BVH construction:
Query:
GPU中对光线追踪的优化
(如下内容只涉及GPU光线追踪的开发经验总结,不涉及其他方面,谨慎考虑,小心被骗)