首页 文章

如何在多GPU系统中根据PCI供应商,设备和总线ID将OpenCL设备与特定GPU相匹配?

提问于
浏览
15

我希望能够在由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的解决方案 .

5 回答

  • 7

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

  • 0

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

  • 1

    不幸的是,由于openCL的抽象性,你所寻找的答案并不漂亮 .

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

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

  • 0

    似乎Anteru的答案是正确的,但只有你运行的是linux / mac . 经过一些测试后,似乎Windows无法识别这些特定于供应商的扩展 . (我在Geforce GTX Titan和ATI Radeon R9上测试了它)

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

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

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

  • 1

    我开发了一个库来做到这一点:保持OpenCL模拟不要踩到彼此的脚趾 .

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

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

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

    它适用于这些平台:

    • nvidia(仅限GPU)

    • amd(CPU和/或GPU)

    • intel(仅限CPU)

    • apple(CPU和/或GPU)

    请注意,它不会让你选择要使用的设备,但为您选择一个 . 如果一个程序的两个实例使用该库,他们就会知道它并赢得了't run on the same device (if you have too, of course). It is also not able, right now, to detect if the video card is used for the display. But at least it'的开始!

相关问题