例如,当我使用带有CUDA C/C++和GPUDirect 2.0 P2P的多GPU系统,以及使用嵌套的picture开关(如图所示)时,我必须知道通过它们的PCI总线ID在任意两个GPU之间切换了多少次,以优化数据传输和计算分配。
或者,如果我已经知道带有PCIe开关的硬件PCIe拓扑,那么我必须知道,任何GPU卡上的硬件PCIe插槽都连接到哪个硬件上。
如我所知,即使我已经知道带有PCIe开关的硬件PCIe拓扑,但这些标识符并不是硬绑定到板上的PCIe插槽上,而且这些ID可能会更改,并且因系统的运行而有所不同:
有详细设备树的PCIe总线的拓扑结构和板上的PCIe槽数、和Linux的最佳方法是什么?
发布于 2015-08-19 10:06:04
PCI设备(端点)具有唯一的地址。本地址由三部分组成:
例如,设备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
在这里您可以看到sys-fs将总线02的设备00到03列出为连接到总线00,设备11,函数0。
根据这些信息,您可以重建完整的PCI总线树。除非添加或删除设备,否则启动后树始终是相同的。
windows设备管理器提供相同的信息。属性对话框显示设备类型、供应商和位置:例如,用于集成Intel 4600图形的PCI bus 0, device 2, function 0
。
目前,我不知道如何在Windows环境下通过脚本或编程语言获得这些信息,但是在互联网上有提供这些信息的商业工具和免费工具。也许有一个API。
发布于 2017-10-18 21:43:27
下面是不需要解析注册表的脚本版本。所有的信息(在这里使用)都可以在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]
}
}
}
}
}
发布于 2016-05-10 09:43:06
在Windows上,您可以使用例如:下面的Powershell脚本与中的devcon.exe工具一起使用:
Function Get-BusFunctionID {
$Devices = .\devcon.exe find PCI\*
for($i=0; $i -lt $Devices.length; $i++) {
if(!($Devices[$i] -match "PCI\\*")) {
continue
}
$DevInfo = $Devices[$i].split(":")
$deviceId = $DevInfo[0]
$locationInfo = (get-itemproperty -path "HKLM:\SYSTEM\CurrentControlSet\Enum\$deviceID" -name locationinformation).locationINformation
$businfo = Resolve-PCIBusInfo -locationInfo $locationinfo
new-object psobject -property @{
"Name" = $DevInfo[1];
"PnPID" = $DevInfo[0]
"PCIBusID" = $businfo.BusID;
"PCIDeviceID" = $businfo.DeviceID;
"PCIFunctionID" = $businfo.FunctionID
}
}
}
Function Resolve-PCIBusInfo {
param (
[parameter(ValueFromPipeline=$true,Mandatory=$true)]
[string]
$locationInfo
)
PROCESS {
[void]($locationInfo -match "\d+,\d+,\d+")
$busId,$deviceID,$functionID = $matches[0] -split ","
new-object psobject -property @{
"BusID" = $busID;
"DeviceID" = "$deviceID"
"FunctionID" = "$functionID"
}
}
}
用法示例:
Get-BusFunctionID | Where-Object {$_.PCIBusID -eq 0 -and $_.PCIDeviceID -eq 0} | Format-Table
Get-BusFunctionID | Sort-Object PCIBusID, PCIDeviceID, PCIFunctionID | Format-Table -GroupBy PCIBusID
Get-BusFunctionID | Sort-Object PCIBusID, PCIDeviceID, PCIFunctionID | Out-GridView
https://stackoverflow.com/questions/32073667
复制相似问题