2012-06-21 41 views
0

作为OpenCL的新手,我想知道以下情况是否可行。OpenCL - 主内核填充缓冲区并在子内核上运行

在内存中,创建了10个长度为10000的缓冲区,或者一个10xN图像缓冲区作为缓存。

第一个内核将在缓存中填充一行,并查询另一个内核在该行上执行一些操作。当第二个内核完成后,第一个内核可以计算一个新行并替换旧行,同样的过程继续,直到第一个内核没有更多的任务。

这个场景是否合理,在GPU编程中是否有用?

回答

1

OpenCL不允许内核调用其他内核。但你有一些选择。

  1. 让第一个内核调用另一个非内核函数。工作项目之间的工作分配在这里不会改变 - 所以如果你有10个并行工作项(线程)正在执行,每行有一个工作项,那么每个线程将对非内核函数中的相同数据进行操作。

  2. 多个内核可以一个接一个地强化,但这是由主机协调的。这确实允许线程间工作的重新分配,但可以更复杂得多,选项1

一个关键创建快速的OpenCL代码是区分你的工作纳入工作项目,通常越多越好做。如果你的第一个填充行的内核只能分成10个工作项目,但你的第二个内核在这一行上处理可以分解成1000个工作项目,那么你一定要使用选项2作为第二个部分在具有大量内核的设备(如现代GPU)上更有效地分割。少数工作项目(如10)只能使用这些可用处理能力的一小部分。

(增补)

OpenCL内核在GPU上执行的是数据并行的,这意味着只有一个内核可以同时执行,但每个线程的工作原理与不同的数据片段。为了适应这个模型,可能需要重新思考你的算法。

从您在评论中所写的内容来看,听起来像是由于内存限制,一次只能运行10个项目。但请注意,OpenCL中没有动态内存分配。所有缓冲区都在前面声明。所以主机应该确定有多少任务可以放入可用内存并运行批量的工作项目(通过适当的缓冲区传输)。

又如何填充缓冲区?从文件? OpenCL内核无法读取文件,网络等,因此如果这是原始数据如何加载,则必须在主机上完成。但是,如果这些图像缓冲区是从其他源创建的(例如通过算法或其他内存源),那么应该可以正常工作(尽管您还需要将任何其他内存源也复制到GPU中) 。

+0

这就是我的情况。上述第一个和第二个任务的工作项目比例为1:2000。所以选项2是我的问题的答案。我在我的例子中提到了10行,因为我需要一些缓冲区来保存第二个任务的数据,而且如果它开始执行所有任务,内存需求会很大。因此,如果第一个内核有N个任务,是否可以告诉只同时运行10个工作项,并且只有在第二个任务完成时才继续新的工作项? –

+0

我也在考虑只在主机上保留第一个任务,并将输入数据写入gpu并将第二个任务排入队列,并在完成后读取结果并向gpu写入一组新输入并再次入队。但是如果第一个任务也可以在GPU上完成,我不需要从主机写入gpu那么多。 –

+0

@ s093294不同的GPU硬件会有不同的表现。在主机上保留第一项任务可能会变得更快,具体取决于将内存从主机复制到设备需要多长时间,这取决于需要复制的设备,主机和内存量。您可能想要尝试两种方法,并选择最终使用硬件最快的方案。 – prunge