OpenCL:一个程序 运行 一个多个设备
OpenCL: One Program running one multiple devices
我已经找到了
OpenCL: Running CPU/GPU multiple devices.
但我仍然有疑问 (3) 如何在多个设备上 运行 一个程序。配方如下吗?(Q1)
创建您要使用的设备。
为每个设备创建一个上下文。
为每个上下文调用 clBuilProgram 来构建程序
每个程序调用 clCreateCommandQueue 为每个上下文构建一个命令队列
对于每个上下文和每个函数参数调用 clCreateBuffer。
或者我必须连接 CommandQueues。(Q2)
有人有示例代码或 link 教程吗? (Q3)
您创建一个包含所有设备的上下文。上下文构造采用设备列表。您为上下文编译程序一次。您为程序调用一次 clBuildProgram,或 clCompileProgram 和 clLinkProgram,列出所有设备或不列出任何设备并让它为上下文中的所有设备构建。为上下文中的每个设备创建一个命令队列。为您要访问的每个数组创建一个缓冲区。如果你想在不同的设备上处理数组的不同部分,你可以创建两个缓冲区,或者使用子缓冲区将它分成几个部分。
如果您对针对所有设备的同一个程序不满意并希望进一步优化,您可以为每个设备创建一个单独的程序,或者创建一次程序并为每个传入宏的设备分别调用 clCompileProgram。
如果您要定位的所有设备都来自同一平台,那么@Lee 的响应很好(例如 AMD GPUs + CPU,或 Intel GPUs + CPU)。如果您希望必须针对多种平台(例如,将 Nvidia GPU 与 AMD GPU 和 CPU 相结合),那么您的上下文不能从一个平台跨越到另一个平台——至少,您需要每个平台一个上下文.
我看到的选项是:
- 每个上下文一个设备。设备之间的同步需要复制到主机内存。
- 一个环境下的多个设备,只使用一个平台。这样可以更轻松地在同一上下文中的设备之间共享数据。
- 来自同一平台的多个设备在一个上下文中,每个平台一个上下文。允许您同时使用多个平台,同时为您提供在一个环境中拥有多个设备的好处。
选项 3 在工作分配方面有点棘手,因为您有两个级别来划分工作 - contexts/platforms 和设备之间。恕我直言,选项 1 是访问计算机中每个 OpenCL 设备的最简单方法,无论其平台如何。选项 2 只有在保证您始终使用来自一个供应商的设备(即一个平台上的所有设备)的情况下才真正值得。如果同时以 GPU+CPU 为目标,这个假设很快就会破灭。
完成上述三个选项后,您将需要至少一个命令队列每个设备。您需要为每组相同的设备编译 OpenCL 内核。每个供应商的每一代 GPU 都是不同的。至少,您最终可能会得到在一台设备和另一台设备之间具有不同定义的宏。最坏的情况是,一台设备和另一台设备可能有不同的算法(如果使用上面的选项 1 更容易处理)。
我已经找到了 OpenCL: Running CPU/GPU multiple devices.
但我仍然有疑问 (3) 如何在多个设备上 运行 一个程序。配方如下吗?(Q1)
创建您要使用的设备。
为每个设备创建一个上下文。
为每个上下文调用 clBuilProgram 来构建程序
每个程序调用 clCreateCommandQueue 为每个上下文构建一个命令队列
对于每个上下文和每个函数参数调用 clCreateBuffer。
或者我必须连接 CommandQueues。(Q2)
有人有示例代码或 link 教程吗? (Q3)
您创建一个包含所有设备的上下文。上下文构造采用设备列表。您为上下文编译程序一次。您为程序调用一次 clBuildProgram,或 clCompileProgram 和 clLinkProgram,列出所有设备或不列出任何设备并让它为上下文中的所有设备构建。为上下文中的每个设备创建一个命令队列。为您要访问的每个数组创建一个缓冲区。如果你想在不同的设备上处理数组的不同部分,你可以创建两个缓冲区,或者使用子缓冲区将它分成几个部分。
如果您对针对所有设备的同一个程序不满意并希望进一步优化,您可以为每个设备创建一个单独的程序,或者创建一次程序并为每个传入宏的设备分别调用 clCompileProgram。
如果您要定位的所有设备都来自同一平台,那么@Lee 的响应很好(例如 AMD GPUs + CPU,或 Intel GPUs + CPU)。如果您希望必须针对多种平台(例如,将 Nvidia GPU 与 AMD GPU 和 CPU 相结合),那么您的上下文不能从一个平台跨越到另一个平台——至少,您需要每个平台一个上下文.
我看到的选项是:
- 每个上下文一个设备。设备之间的同步需要复制到主机内存。
- 一个环境下的多个设备,只使用一个平台。这样可以更轻松地在同一上下文中的设备之间共享数据。
- 来自同一平台的多个设备在一个上下文中,每个平台一个上下文。允许您同时使用多个平台,同时为您提供在一个环境中拥有多个设备的好处。
选项 3 在工作分配方面有点棘手,因为您有两个级别来划分工作 - contexts/platforms 和设备之间。恕我直言,选项 1 是访问计算机中每个 OpenCL 设备的最简单方法,无论其平台如何。选项 2 只有在保证您始终使用来自一个供应商的设备(即一个平台上的所有设备)的情况下才真正值得。如果同时以 GPU+CPU 为目标,这个假设很快就会破灭。
完成上述三个选项后,您将需要至少一个命令队列每个设备。您需要为每组相同的设备编译 OpenCL 内核。每个供应商的每一代 GPU 都是不同的。至少,您最终可能会得到在一台设备和另一台设备之间具有不同定义的宏。最坏的情况是,一台设备和另一台设备可能有不同的算法(如果使用上面的选项 1 更容易处理)。