我在C#中有一个重型算法,它需要两个大约10000x5000的大型Bitmap,并在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发布于 2012-09-04 21:48:17
是的,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)你是否考虑过从几何角度而不是图像角度进行造型?即每一个三角形,每一个顶点,从相机投射光线并检测屏幕上的位置。您可以对三角形上的剩余点进行插值,并对结果进行z缓冲,以防止重新绘制像素。
4)如果你只是在处理图形,opengl/directx已经有你需要的东西了吗?
发布于 2012-09-04 17:26:00
对于您的特定问题: for循环是可以的(尽管不是最优的);在GPU上不可能进行递归。
一般来说,一个在GPU上运行良好的算法需要有很多独立的数据并行操作。许多位图操作都属于这一类,另一方面,光线跟踪可能是具有挑战性的。
如果你可以修改你的算法,使你在最高层有很多(几千个)独立的块,那么块中较低层的依赖性应该是可以的。
对于这样一个一般性的话题,我想我只能说这么多了。
发布于 2012-09-04 22:07:38
在使用OpenCL之前,我会先把它翻译成一个多线程的C程序。你已经观察到这一步的速度有了很大的提高,而且容易多了。此外,要用OpenCL编写内核,您需要使用OpenCL C,它非常类似于普通的C-因此,从这个中间步骤开始的转换步骤将比直接从C#开始要容易得多
最后,要做OpenCL版本,你必须做的是与图形处理器共享来自主机的照片的内存(事实上,对于图像,它有专门的内存API,仅用于知道像素编码与OpenGL兼容的图像),然后创建一个raycheck内核,然后从主机队列中为每个块/三角形排列raycheck内核。
这里有一个来自ATI的关于OpenCL的很好的介绍性演讲。
http://www.youtube.com/watch?v=ecYIsu83c0I
https://stackoverflow.com/questions/12260256
复制相似问题