我正在编写自己的图形库(是的,这是我的作业 :)),并使用CUDA快速进行所有渲染和计算。我在绘制填充三角形时遇到了问题。我将其编写为一个进程绘制一个三角形的方式。当场景中有许多小三角形时,它的效果非常好,但当三角形很大时,性能会完全崩溃。我的想法是进行两次通行。首先只计算有关扫描线(从这里到那里绘制)的信息表。这将是类似于当前算法中每个进程的三角形计算。然后在第二遍通行中,真正绘制具有一个以上进程的三角形的扫描线。但这样做是否足够快?也许有更好的解决方案吗?
我怀疑您对CUDA及其使用方式存在一些误解,尤其是当您提到一个“进程”时,在CUDA术语中并不存在这样的东西。
对于大多数CUDA应用程序来说,获得良好性能有两个重要因素:优化内存访问和确保warp中每个“活动”的CUDA线程同时执行相同操作。这两个方面都似乎很重要,也与您的应用程序相关。
为了优化内存访问,您需要确保从全局内存读取和写入全局内存的操作是合并的。您可以在CUDA编程指南中了解更多信息,但这实质上意味着,半个warp中相邻的线程必须从相邻的内存位置进行读或写操作。此外,每个线程应该每次读取或写入4、8或16个字节。
如果您的内存访问模式是随机的,则可能需要考虑使用纹理内存。当需要引用块中其他线程已读取的内存时,应使用共享内存。
在您的情况下,我不确定您的输入数据是什么,但您至少应该确保您的写操作是合并的。获取高效的读取也可能需要投入一定的努力。
对于第二部分,我建议每个CUDA线程处理输出图像中的一个像素。使用这种策略时,您应该注意内核中的循环,这些循环将根据每个线程的数据执行更长或更短的时间。warp中的每个线程应按相同顺序执行相同数量的步骤。唯一的例外是,如果warp中有一些线程不执行任何操作,而其余线程一起执行相同的操作,则没有真正的性能惩罚。不是要无礼,但这不是图形卡本来就设计用来做的吗?使用标准的OpenGL和Direct3D API似乎更有意义。
为什么不使用API来进行基本渲染,而不是使用更低级别的CUDA?然后,如果您希望执行不受支持的其他操作,可以使用CUDA在其上应用它们。或者将它们实现为着色器。