更新了不同的问题描述。我之前提出的问题所建议的双向路径跟踪不是一种选择。
我有一个蒙特卡罗代码,可以使用OpenCL进行一些计算(物理模拟)。主机代码是用Python和PyOpenCL编写的。 OpenCL内核的最终结果是图像的坐标图(x,y位置+强度/灰度值)(检测器数据)。我有3个矢量/ 1D阵列(x位置,y位置和灰度值各一个)。每个1D阵列具有大约1e6到1e8个,其中x,y是int,灰色值是浮点数。要创建的图像是几个1000x1000像素(1e6到1e7像素) 最终,我需要为每次运行创建多个图像(每个图像具有不同的坐标元组),因此效率和低内存使用变得非常重要。
从这些数据生成2D数组或图像的最快方法是什么?对同一位置(x,y)的多次写入确实发生,我无法找到并行或模拟期间执行此操作的良好解决方案(因为可能同时写入图像中的相同位置)。
我目前所做的是将3个矢量/ 1D数组复制回主机,并使用内联C函数在主机上连续生成图像。
代码中最耗时的部分是为3个1D阵列创建输出缓冲区阵列,然后在内核完成时从设备复制到主机。
如果我能做到这一点会很棒:
i)将数据保存在设备上并使用第二个内核进行映像生成(已测试,但如果是串行完成则非常慢)
ii)或者如果我可以在内核运行时进行图像生成,从而整体摆脱1D阵列。
ii)是首选,但我不知道该怎么做。 write_image是否识别多个工作项是否要写入同一个数组索引? 我已经测试并行化i)为两个工作组生成2个独立的2D图像数组,每个工作组有1个工作项,每个项目迭代超过一半的1D向量(工作),但是对于更多的工作项和独立的图像,创建附加的开销2D数组花费的时间太长,占用的内存太多。
任何想法都表示赞赏。
答案 0 :(得分:2)
Python对于高性能应用程序来说并不是很好,特别是如果它涉及循环 - 与Matlab类似。
但是如果你想坚持使用Python并并行化你的代码,最好的方法是使用PyCuda,你可以为每个像素创建一个线程并在GPU上运行计算。
请注意,最有效的光线追踪是向后光线追踪,它将光线从相机发送到场景(例如,每个像素一条光线),这样你就不会浪费光线。否则永远不会到达相机。在尝试并行化代码之前,可能首先要了解并实现更高效的算法。
如果需要全局效果,可以查看(双向)路径跟踪和照片映射。