1

我在 C# 中有一个重型算法,它需要两个Bitmap大约 10000x5000 的大 s 并在 3D 模型上执行照片和光线碰撞操作,以将照片映射到 3D 模型上。

我想知道是否可以将这样的算法转换为 OpenCL 以优化算法期间的并行操作。但在请您详细介绍算法之前,我想知道如何调查我的算法是否可转换为 OpenCL。

我在 OpenCL 方面没有经验,我想知道是否值得进入并了解它是如何工作的。有没有我必须寻找的东西在显卡上肯定不起作用?(for循环,递归)

更新:

我的算法类似于:

foreach photo
    split the photo in 64x64 blocks
    foreach block
        cast a ray from the camera to the 3D model
        foreach triangle in 3D model
            perform raycheck
4

3 回答 3

2

是的,opencl 非常适合这种类型的工作。光线投射是gpu硬件可以大放异彩的地方。

一种划分方法:

foreach photo - work done by host application. (openmp?)
foreach block - use one opencl work group per block
foreach triangle in 3D model - single work item

当你实现这个算法时,还有一些其他的事情需要考虑。

1) 每块是否总是有 64^2 条光线要投射?

2) 什么比例的光线会“击中”图像和/或几何图形?条件分支会损害 gpu 硬件的性能。

3)您是否考虑过从几何角度而不是图像进行投射?即foreach三角形,foreach顶点,从相机投射光线并检测屏幕上的位置。您也许可以对三角形上的剩余点进行插值,并对结果进行 z 缓冲,以防止重绘像素。

4) 如果您只是处理图形,opengl/directx 是否已经具备您需要的功能?

于 2012-09-04T13:48:17.317 回答
1

对于您的具体问题: for 循环很好(尽管不是最佳的);递归在 GPU 上是不可能的。

一般来说,在 GPU 上运行良好的算法需要有大量独立的数据并行操作。很多位图操作都属于这一类,另一方面,光线追踪可能具有挑战性。

如果您可以修改您的算法,以便在最高级别有很多(数千个)独立块,那么块内较低级别的依赖关系应该没问题。

对于这样一个笼统的话题,我想这就是我所能说的。

于 2012-09-04T09:26:00.277 回答
1

在 OpenCL 中执行此操作之前,我将采取中间步骤将其转换为多线程 C 程序。您已经从这一步观察到速度大幅提高,而且要容易得多。此外,要在 OpenCL 中编写内核,您需要使用与普通 C 非常相似的 OpenCL C - 因此从这个中间步骤开始的翻译步骤将比直接从 C# 更容易

最后,要做 OpenCL 版本,您要做的就是与 GPU 共享来自主机的照片内存(实际上对于图像,它具有特殊的内存 API,仅用于知道像素编码的图像以某种方式与 OpenGL 兼容) 然后创建一个 raycheck 内核,然后从主机为每个块/三角形排队 raycheck 内核。

ATI 在 OpenCL 上有一个很好的介绍性演讲

http://www.youtube.com/watch?v=ecYIsu83c0I

于 2012-09-04T14:07:37.620 回答