OpenCL:一个程序运行一个或多个设备

OpenCL:一个程序运行一个或多个设备,opencl,Opencl,我已经找到这个了 但我还有一些问题(3)如何在多台设备上运行程序。配方如下?(Q1) 创建要使用的设备 为每个设备创建一个上下文 对于每个上下文调用clBuilProgram来构建一个程序 对于每个程序,调用clCreateCommandQueue为每个上下文构建一个命令队列 对于每个上下文和每个函数参数,调用clCreateBuffer 或者我必须连接命令队列。(Q2) 有人有一些示例代码或教程的链接吗?(Q3)您可以创建一个包含所有设备的上下文。上下文构造需要一个设备列表。为上下文编译一次

我已经找到这个了

但我还有一些问题(3)如何在多台设备上运行程序。配方如下?(Q1)

  • 创建要使用的设备

  • 为每个设备创建一个上下文

  • 对于每个上下文调用clBuilProgram来构建一个程序

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

  • 对于每个上下文和每个函数参数,调用clCreateBuffer

  • 或者我必须连接命令队列。(Q2)


    有人有一些示例代码或教程的链接吗?(Q3)

    您可以创建一个包含所有设备的上下文。上下文构造需要一个设备列表。为上下文编译一次程序。您可以为该程序调用一次clBuildProgram或clCompileProgram和clLinkProgram,列出所有设备或不列出任何设备,并让它在上下文中为所有设备生成。为上下文中的每个设备创建命令队列。为要访问的每个阵列创建缓冲区。如果要在不同的设备上处理阵列的不同部分,可以创建两个缓冲区,或使用子缓冲区将其划分为多个部分


    如果您对针对所有设备的同一计划不满意,并希望进一步优化,您可以为每个设备创建单独的计划,或者创建一次程序,并分别为传入宏的每个设备调用clCompileProgram。

    如果目标设备来自同一平台,则@Lee的响应良好(例如AMD GPU+CPU或Intel GPU+CPU)。如果您希望针对混合平台(例如,结合Nvidia GPU、AMD GPU和CPU),则您的上下文无法从一个平台跨到另一个平台-至少,每个平台需要一个上下文

    我看到的选项有:

  • 每个上下文一个设备。设备之间的同步需要复制到主机内存
  • 一个上下文中有多个设备,仅使用一个平台。这可以使在同一上下文中的设备之间共享数据变得更容易
  • 在一个上下文中,来自同一平台的多个设备,每个平台一个上下文。允许您同时使用多个平台,同时为您提供在一个环境中使用多个设备的好处
  • 选项3在工作分配中有点棘手,因为您有两个工作分配级别-在上下文/平台之间和在设备之间。选项1,IMHO,是访问计算机中每个OpenCL设备的最简单方法,而不管它们的平台如何。只有在保证始终使用一家供应商的设备(即一个平台中的所有设备)时,选项2才是真正值得的。如果同时以GPU+CPU为目标,这种假设很快就会被打破


    完成上述三个选项后,每个设备至少需要一个命令队列。您需要为每组相同的设备编译OpenCL内核。每个供应商的每一代GPU都是不同的。至少,最终可能会出现宏在不同的设备之间具有不同的定义。在最坏的情况下,不同的设备可能有不同的算法(如果使用上面的选项1,则更容易处理)。

    您希望使用的设备类型是什么,CPU和GPU?不幸的是,OpenCL程序需要针对每种设备类型进行调优(代码可能会非常不同)。我将我的OpenCL多设备类型工作限制为在匹配的GPU对上运行。不,我只想在多个GPU(同一供应商)上运行该算法。这是否意味着我可以为来自不同设备类型(和或不同平台形式)的设备创建单个上下文?不是不同的平台,不。每个平台应该有一个上下文。选项2和3在许多情况下可能更有效,因为依赖项和数据移动可以在驱动程序堆栈中处理(可能由设备本身处理),而无需将应用程序线程踢回CPU。如果您使用的是移动SoC(不太可能使用两种不同的平台),或者是多GPU桌面,大多数人都从同一个供应商那里购买,这将允许直接进行GPU->GPU内存传输,那么很可能会出现这种情况。在Linux上的实践中,我发现Intel CPU和IGP(NEO)运行时确实会产生两个独立的平台,这意味着至少对于这些英特尔系统,我们正在考虑的选项1是最有意义的。