OpenCL:一个程序在多个设备上运行

4
我已经找到了这个OpenCL: Running CPU/GPU multiple devices,但我仍有三个问题:如何在多个设备上运行程序?是按照以下步骤进行的吗?(Q1)
  1. 创建您想要使用的设备。

  2. 为每个设备创建一个上下文。

  3. 对于每个上下文,调用clBuilProgram来构建程序。

  4. 对于每个程序,调用clCreateCommandQueue为每个上下文构建一个命令队列。

  5. 对于每个上下文和每个函数参数,调用clCreateBuffer。

还是必须连接CommandQueues。(Q2)
有人有示例代码或教程链接吗? (Q3)

1
您希望使用哪些设备类型,CPU 和 GPU?不幸的是,OpenCL 程序需要针对每种设备类型进行调整(代码可能会有很大不同)。我将我的 OpenCL 多设备类型工作限制为在匹配的 GPU 对上运行。 - Tim Child
不,我只想在多个相同厂商的GPU上运行算法。 - user1235183
2个回答

6
你需要创建一个包含所有设备的上下文。上下文构建需要一份设备列表。你需要为上下文编译程序一次。调用clBuildProgram或clCompileProgram以及clLinkProgram一次,列出所有设备或不列出任何设备并让其为上下文中的所有设备构建。为上下文中的每个设备创建一个命令队列。为要访问的每个数组创建一个缓冲区。如果你想在不同的设备上处理数组的不同部分,则可以创建两个缓冲区,或使用子缓冲区将其分成几个部分。
如果你不满意针对所有设备的同一程序,并希望进一步优化,则可以为每个设备创建单独的程序,或者创建一次程序,并为每个设备单独调用clCompileProgram并传递宏。

这是否意味着我可以为来自不同设备类型(和/或不同平台)的设备创建单个上下文? - user1235183
不是不同的平台,是针对每个平台应该只有一个上下文。 - Lee

1
如果你的目标设备都来自同一平台,那么@Lee的回答就可以了(例如AMD GPU + CPU,或Intel GPU + CPU)。如果你希望针对混合平台进行目标设定(例如将Nvidia GPU与AMD GPU和CPU组合起来),那么你的上下文不能从一个平台跨越到另一个平台-至少,你需要每个平台一个上下文。
我认为选择如下:
1.每个上下文一个设备。设备之间的同步需要复制到主机内存。
2.在一个上下文中使用多个设备,只使用一个平台。这可以使在同一上下文中的设备之间共享数据更容易。
3.在一个上下文中使用来自同一平台的多个设备,每个平台一个上下文。允许您同时利用多个平台,同时给您拥有一个上下文中多个设备的好处。
选项3在工作分配方面有点棘手,因为工作在两个级别上被划分 - 在上下文/平台之间和在设备之间。选项1是我认为最容易获得计算机中每个OpenCL设备访问权限的方法,无论它们的平台如何。如果保证始终在一个供应商的设备上工作(即在一个平台上的所有设备),则选项2只有真正的价值。如果同时针对GPU + CPU进行目标设定,这种假设很快就会破裂。

在完成以上三个选项后,每个设备至少需要一个命令队列。您需要为每组相同的设备编译OpenCL内核程序。每个供应商的每个GPU代系都是不同的。您最起码可能会得到不同的宏定义,从一个设备到另一个设备有所不同。在最坏的情况下,您可能会在一个设备上得到与另一个设备完全不同的算法(如果使用上述“选项1”,则更容易处理)。


选项2和3在许多情况下也更有效,因为依赖关系和数据移动可以在驱动程序堆栈(或设备本身)中处理,而无需将应用程序线程重新返回到CPU。如果您正在使用移动SoC(在那里您很有可能根本不会得到两个不同的平台),或者拥有一个多GPU桌面计算机,在这种情况下,大多数人都从同一供应商购买,这将允许直接进行GPU-> GPU内存传输,那么它们很可能是您所处的情况。 - Lee
在Linux实践中,我发现Intel CPU和IGP(NEO)运行时确实会产生两个独立的平台,这意味着至少对于这些Intel系统,我们正在考虑选项1是最合理的。 - Steven Lu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接