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

OpenCL: One Program running one multiple devices

我已经找到了 OpenCL: Running CPU/GPU multiple devices.

但我仍然有疑问 (3) 如何在多个设备上 运行 一个程序。配方如下吗?(Q1)

  1. 创建您要使用的设备。

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

  3. 为每个上下文调用 clBuilProgram 来构建程序

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

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

或者我必须连接 CommandQueues。(Q2)

有人有示例代码或 link 教程吗? (Q3)

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

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

如果您要定位的所有设备都来自同一平台,那么@Lee 的响应很好(例如 AMD GPUs + CPU,或 Intel GPUs + CPU)。如果您希望必须针对多种平台(例如,将 Nvidia GPU 与 AMD GPU 和 CPU 相结合),那么您的上下文不能从一个平台跨越到另一个平台——至少,您需要每个平台一个上下文.

我看到的选项是:

  1. 每个上下文一个设备。设备之间的同步需要复制到主机内存。
  2. 一个环境下的多个设备,只使用一个平台。这样可以更轻松地在同一上下文中的设备之间共享数据。
  3. 来自同一平台的多个设备在一个上下文中,每个平台一个上下文。允许您同时使用多个平台,同时为您提供在一个环境中拥有多个设备的好处。

选项 3 在工作分配方面有点棘手,因为您有两个级别来划分工作 - contexts/platforms 和设备之间。恕我直言,选项 1 是访问计算机中每个 OpenCL 设备的最简单方法,无论其平台如何。选项 2 只有在保证您始终使用来自一个供应商的设备(即一个平台上的所有设备)的情况下才真正值得。如果同时以 GPU+CPU 为目标,这个假设很快就会破灭。

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