【问题标题】:OpenCL: One Program running one multiple devicesOpenCL:一个程序运行一个多设备
【发布时间】:2015-07-24 22:53:41
【问题描述】:

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

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

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

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

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

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

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

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

有人有一些示例代码或教程链接吗? (第三季度)

【问题讨论】:

  • 您希望使用哪些设备类型,CPU 和 GPU?不幸的是,OpenCL 程序需要针对每种设备类型进行调整(代码可能完全不同)。我将我的 OpenCL 多设备类型工作限制为在匹配的 GPU 对上运行。
  • 不,我只想在多个 GPU(同一供应商)上运行算法。

标签: opencl


【解决方案1】:

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

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

【讨论】:

  • 这是否意味着我可以为来自不同设备类型(和/或不同平台)的设备创建单个上下文?
  • 不是不同的平台,不。每个平台一个上下文应该可以工作。
【解决方案2】:

如果您定位的所有设备都来自同一个平台,那么@Lee 的响应很好(例如 AMD GPUs + CPU,或 Intel GPUs + 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 内存传输。
  • 在 Linux 上的实践中,我发现 Intel CPU 和 IGP (NEO) 运行时确实产生了两个独立的平台,这意味着至少对于这些 Intel 系统,我们正在研究选项 1感觉。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-18
  • 2018-05-27
  • 2017-07-01
  • 2021-02-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多