可以跨越OpenCL内核在CPU和GPU上并发运行

时间:2010-07-14 11:24:34

标签: opencl gpgpu

让我们假设我的计算机有多核处理器和GPU。我想写一个OpenCL程序,它运行在平台的所有核心上。这是可能的还是我需要选择运行内核的单个设备?

4 个答案:

答案 0 :(得分:2)

不,你不能在CPU和GPU上自动跨越内核,它可以是其中之一。

您可以这样做,但这将涉及手动创建和管理两个命令队列(每个设备一个)。

看到这个帖子: http://devforums.amd.com/devforum/messageview.cfm?catid=390&threadid=124591&messid=1072238&parentid=0&FTVAR_FORUMVIEWTMP=Single

答案 1 :(得分:2)

理论上是的,你可以,CL API允许它。但是平台/实现必须支持它,我认为大多数CL实现都不支持它。

为此,获取CPU设备和GPU设备的cl_device_id,并使用clCreateContext为这两个设备创建上下文。

答案 2 :(得分:2)

一个上下文只能用于一个平台。如果您的多设备代码需要跨平台工作(例如,Intel平台CPU OpenCL和NVidia GPU),那么您需要单独的上下文。

但是,如果GPU和CPU恰好位于同一平台上,那么可以使用一个上下文。

如果您在同一平台上使用多个设备(两个相同的GPU,或来自同一制造商的两个GPU),那么您可以共享上下文 - 只要它们都来自单个clGetDeviceIDs调用。

编辑: 我应该补充一点,GPU + CPU上下文并不意味着任何自动管理的CPU + GPU执行。通常,最佳做法是让驱动程序分配一个可由GPU进行DMA处理的内存缓冲区,以获得最佳性能。如果您在相同的上下文中拥有CPU和GPU,则可以在两个设备之间共享这些缓冲区。

您仍然需要自己拆分工作量。我最喜欢的负载平衡技术是使用事件。每n个工作项,将一个事件对象附加到命令(或将标记排入队列),并等待您在之前设置n个工作项(前一个)的事件。如果您不必等待,那么您需要在该设备上增加n,如果您必须等待,那么您应该减少n。这将限制队列深度,n将徘徊在完美深度附近以保持设备忙碌。无论如何都需要这样做,以避免导致GUI渲染饥饿。只需在每个命令队列中保留n个命令(CPU和GPU具有单独的n),它将完全分开。

答案 3 :(得分:1)

您无法将内核跨越到多个设备。但是如果您运行的代码不依赖于其他结果(即:处理16kB数据块,需要大量处理),您可以在GPU和CPU上启动相同的内核。并在GPU上放置一些块,在CPU上放置一些块。

这样可以提高性能。

您可以这样做,创建为CPU和GPU共享的clContext,以及2个命令队列。

这不适用于所有内核。有时内核代码适用于所有输入数据,并且无法以部分或块的形式分开。