16

我希望能够在由 PCI ID 标识的多 GPU 系统上将 OpenCL 设备与系统中的 GPU 进行匹配。

例如,如果我有一个带有多个 GPU 的系统,可能来自不同的供应商,我可以通过枚举 PCI 总线来列出设备。这给了我 PCI 供应商、设备和总线 ID。如果我根据某些选择标准选择这些 (GPU) PCI 设备之一用于 OpenCL 计算,如何将其与 OpenCL 设备匹配?

我可以使用clGetDeviceIDs()在 OpenCL 中枚举 GPU 设备,但没有明显的方法可以将 OpenCL 设备与 PCI 设备匹配。OpenCL 函数clGetDeviceInfo()提供对 PCI 供应商 ID 和设备名称的访问,但不提供对 PCI 设备或总线 ID 的访问。我可以尝试将 PCI 设备名称与 OpenCL 设备名称相匹配,但您可能拥有多个相同类型的设备,而且名称并不总是相同。

为什么这是必要的?假设我知道程序 X 在 GPU A 上运行 CUDA 或其他东西。我想避免也将 GPU A 用于 OpenCL 操作,所以我选择 GPU B。然后我需要确定哪个 OpenCL 设备是 GPU A,哪个是 GPU B. PCI ID 似乎是唯一一致且跨平台的识别 GPU 设备的方法。

顺便说一句,CUDA API 确实为您提供了 PCI、总线和插槽 ID(CU_DEVICE_ATTRIBUTE_PCI_BUS_ID、CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID),但 CUDA 仅适用于 NVidia 设备。

理想情况下,我需要使用 C 或 C++ 的解决方案。

4

5 回答 5

10

这样做的方法是使用两个特定于供应商的扩展。对于 AMD,您必须使用CL_DEVICE_TOPOLOGY_AMD可在 Windows 和 Linux 上运行的,并将返回 PCIe 总线 ID,这对于 GPU 来说是唯一的。在 NVIDIA 上,查询设备以获取 CL_DEVICE_PCI_BUS_ID_NV。另见:https ://anteru.net/2014/08/01/2483/

于 2014-08-01T18:48:07.687 回答
1

不幸的是,由于 openCL 的抽象性质,您正在寻找的答案并不漂亮。

我发现可靠地做到这一点的唯一方法是在 openCL 中为平台 + 设备 ID 分配苛刻的工作负载,然后通过 AMD 的 ADL 和 Nvidia 的 NVML 等工具监控进程使用情况。即使是像 cgminer 这样的成熟应用程序也有这个问题,并且经常将 openCL 工作负载与卡指标混为一谈,以至于他们分配配置变量来手动更正它(“gpu-map”)。

我希望现在有一个更好的答案,因为通过 openCL 知道端点后面是哪个设备会很棒!这可能会在未来发生变化,因为 AMD 正在努力将这一层添加到 openCL,正如 arsenm 指出的那样。

于 2014-02-17T04:40:02.003 回答
1

似乎 Anteru 的答案是正确的,但前提是您运行的是 linux/mac。在我做了一些测试之后,似乎 windows 无法识别这些供应商特定的扩展。(我已经在 Geforce GTX Titan 和 ATI Radeon R9 上测试过)

我对您的解决方案是使用带有“CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR”参数的 clGetGLContextInfoKHR() 函数(自 openCL 规范 1.1 起可用),这将确保您获得与执行渲染的同一 GPU 匹配的 openCL 设备 ID。

没错,这不会给你物理总线插槽,但这将确保渲染的 GPU 与计算的 GPU 相同!

此外,假设一个人使用 Nvidia Quadro 卡,那么他可以使用 wgl_nv_gpu_affinity 来确保 openGL 访问特定的 GPU,然后使用 GL 上下文并从中获取 openCL 设备 ID。

于 2014-09-22T10:45:36.330 回答
0

最新的 AMD 版本在 Linux 上具有 cl_device_topology_amd 扩展,它将 CL_DEVICE_TOPOLOGY_AMD 选项添加到 clGetDeviceInfo(),但这是一个非常狭窄的解决方案。

于 2011-09-08T00:34:47.837 回答
0

我开发了一个库来做到这一点:防止 OpenCL 模拟相互踩踏。

你会在这里找到它:https ://github.com/nbigaouette/oclutils/

它首先枚举机器上存在的每个平台的所有平台和每个设备。您选择想要的平台,它将选择可用的最佳设备。我在带有 3 个 nvidia 卡的工作站上使用它:两个 GTX 580 用于 OpenCL 计算,一个 GT 210 用于显示。同时运行两个模拟将分别在两个 GTX 上运行。无需干预。

还有一个很好的类可以保持两个缓冲区同步:一个在主机上,一个在设备上。调用 OpenCL_Array::Host_to_Device() 和 OpenCL_Array::Device_to_Host() 使来回传输变得简单。

它适用于以下平台:

  • 英伟达(仅限 GPU)
  • AMD(CPU 和/或 GPU)
  • 英特尔(仅限 CPU)
  • 苹果(CPU 和/或 GPU)

请注意,它不会让您选择要使用的设备,而是为您选择一个。如果一个程序的两个实例使用该库,它们会知道它并且不会在同一设备上运行(当然,如果你也有的话)。目前,它也无法检测视频卡是否用于显示。但至少这是一个开始!

于 2011-11-22T01:15:44.147 回答