如何在板上找到PCIe总线拓扑和插槽号?

Ale*_*lex 3 c++ windows cuda pci pci-e

例如,当我使用带有CUDA C / C ++和GPUDirect 2.0 P2P的多GPU系统,并且使用嵌套的PCI-Express开关时,如图所示,那么我必须通过其PCI总线ID知道任意两个GPU之间有多少个开关,以优化数据的传输和分配计算。

或者,如果我已经知道具有PCIe开关的硬件PCIe拓扑,那么我必须知道,任何GPU卡都连接到板上的哪个硬件PCIe插槽。 在此处输入图片说明

据我所知,即使我已经知道带有PCIe交换机的硬件PCIe拓扑,这些标识符也不会硬绑定到板上的PCIe插槽,并且这些ID可能会发生变化,并且因系统运行而异:

  • CUDA device_id
  • nvidia-smi / nvml GPU ID
  • PCI总线ID

在Windows和Linux上,通过详细的设备树和板上的PCIe插槽数量发现PCIe总线拓扑的最佳方法是什么?

Pae*_*els 6

PCI 设备(端点)有一个唯一的地址。这个地址有3部分:

  • 总线ID
  • 设备编号
  • 功能ID

例如多功能装置12的上总线3 3被写入BDF概念:03:0C.3。扩展的 BDF 符号添加一个域(主要是 0000)作为前缀:0000:03:0c.3.

Linux 将这些设备列在 /sys/bus/pci/devices

paebbels@debian8:~$ ll /sys/bus/pci/devices/
drwxr-xr-x 2 root root 0 Aug 19 11:44 .
drwxr-xr-x 5 root root 0 Aug  5 15:14 ..
lrwxrwxrwx 1 root root 0 Aug 19 11:44 0000:00:00.0 -> ../../../devices/pci0000:00/0000:00:00.0
lrwxrwxrwx 1 root root 0 Aug 19 11:44 0000:00:01.0 -> ../../../devices/pci0000:00/0000:00:01.0
lrwxrwxrwx 1 root root 0 Aug 19 11:44 0000:00:07.0 -> ../../../devices/pci0000:00/0000:00:07.0
lrwxrwxrwx 1 root root 0 Aug 19 11:44 0000:00:07.1 -> ../../../devices/pci0000:00/0000:00:07.1
...
lrwxrwxrwx 1 root root 0 Aug 19 11:44 0000:00:18.6 -> ../../../devices/pci0000:00/0000:00:18.6
lrwxrwxrwx 1 root root 0 Aug 19 11:44 0000:00:18.7 -> ../../../devices/pci0000:00/0000:00:18.7
lrwxrwxrwx 1 root root 0 Aug 19 11:44 0000:02:00.0 -> ../../../devices/pci0000:00/0000:00:11.0/0000:02:00.0
lrwxrwxrwx 1 root root 0 Aug 19 11:44 0000:02:01.0 -> ../../../devices/pci0000:00/0000:00:11.0/0000:02:01.0
lrwxrwxrwx 1 root root 0 Aug 19 11:44 0000:02:02.0 -> ../../../devices/pci0000:00/0000:00:11.0/0000:02:02.0
lrwxrwxrwx 1 root root 0 Aug 19 11:44 0000:02:03.0 -> ../../../devices/pci0000:00/0000:00:11.0/0000:02:03.0
lrwxrwxrwx 1 root root 0 Aug 19 11:44 0000:03:00.0 -> ../../../devices/pci0000:00/0000:00:15.0/0000:03:00.0
Run Code Online (Sandbox Code Playgroud)

在这里您可以看到 sys-fs 将总线 02 的设备 00 到 03 列为连接到总线 00、设备 11、功能 0

根据这些信息,您可以重建完整的 PCI 总线树。除非您添加或删除设备,否则启动后树总是相同的。

Windows 设备管理器提供相同的信息。属性对话框向您显示设备类型、供应商和位置:例如PCI bus 0, device 2, function 0对于集成的 Intel HD 4600 显卡。

目前,我不知道如何在 Windows 环境中通过脚本或编程语言获取这些信息,但是 Internet 上有提供这些信息的商业和免费工具。也许有一个API。


小智 5

这是不需要解析注册表的脚本版本。win32_pnpentity中提供了所有信息(在此使用)。

Function Get-BusFunctionID { 

    gwmi -namespace root\cimv2 -class Win32_PnPEntity |% {

        if ($_.PNPDeviceID -like "PCI\*") {

            $locationInfo = $_.GetDeviceProperties('DEVPKEY_Device_LocationInfo').deviceProperties.Data

            if ($locationInfo -match 'PCI bus (\d+), device (\d+), function (\d+)') {

                new-object psobject -property @{ 
                    "Name"       = $_.Name
                    "PnPID"      = $_.PNPDeviceID
                    "BusID"      = $matches[1]
                    "DeviceID"   = $matches[2]
                    "FunctionID" = $matches[3]
                }
            }
        }
    }
} 
Run Code Online (Sandbox Code Playgroud)