使用CUDA编程确定GPU链接拓扑结构

3
我正在尝试确定GPU之间的链接拓扑结构,基本上和 nvidia-smi topo -m 的作用差不多。
我找到了一个CUDA示例 topologyQuery,它基本上为每一对GPU调用 cudaDeviceGetP2PAttribute(&perfRank, cudaDevP2PAttrPerformanceRank, device1, device2)
运行此示例的结果(我稍微修改了输出格式)非常令我困惑(与在同一台机器上运行的 nvidia-smi topo -m 的结果进行比较)。
$ ./topologyQuery
        X       1       1       0       0       0       0       0
        1       X       0       1       0       0       0       0
        1       0       X       0       0       0       1       0
        0       1       0       X       0       0       0       1
        0       0       0       0       X       1       1       0
        0       0       0       0       1       X       0       1
        0       0       1       0       1       0       X       0
        0       0       0       1       0       1       0       X

$ nvidia-smi topo -m
        GPU0    GPU1    GPU2    GPU3    GPU4    GPU5    GPU6    GPU7    CPU Affinity
GPU0     X      NV1     NV1     NV2     NV2     PHB     PHB     PHB     0-95
GPU1    NV1      X      NV2     NV1     PHB     NV2     PHB     PHB     0-95
GPU2    NV1     NV2      X      NV2     PHB     PHB     NV1     PHB     0-95
GPU3    NV2     NV1     NV2      X      PHB     PHB     PHB     NV1     0-95
GPU4    NV2     PHB     PHB     PHB      X      NV1     NV1     NV2     0-95
GPU5    PHB     NV2     PHB     PHB     NV1      X      NV2     NV1     0-95
GPU6    PHB     PHB     NV1     PHB     NV1     NV2      X      NV2     0-95
GPU7    PHB     PHB     PHB     NV1     NV2     NV1     NV2      X      0-95

来自https://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__DEVICE.html

cudaDevP2PAttrPerformanceRank: 相对值,表示两个设备之间链接的性能。较小的值表示更好的表现(大多数表现最佳的链接使用值0)。

为什么NV1获得等级1?为什么PHB获得等级0? 我是否误解了cudaDevP2PAttrPerformanceRank查询的目的?

1个回答

1

我不确定您正在测试的是什么系统(它看起来大致像是 DGX-1 输出的结果)。

关于这个问题:

为什么 PHB 得到了等级 0?

如果您运行原始的 topologyQuery 示例代码,您会看到(至少在类似 DGX-1 的系统中),它并没有为每个 GPU 对打印出性能等级。据我所见,它并没有为指示 PHB 的位置打印出性能等级。如果您研究原始代码,原因就很清楚:P2P 不支持这些对组合。然而,您的代码似乎在这些情况下打印出零。因此,我认为这是您的代码与原始的 topologyQuery 代码相比存在缺陷,这导致了这个问题和您的误解。原始代码并没有将 PHB 分配给等级 0。但您修改后的代码确实如此。因此,这是您需要回答的问题。

为什么 NV1 得到了等级 1?

关于其余部分,NV2连接意味着这两个GPU之间有双向NVLink连接(每个方向50GB/s)。在该特定系统中,这将是最高效的连接方式,因此被分配为0链接值。 NV1连接意味着单向NVLink连接(每个方向25GB/s)。这将比NV2连接性能差,因此被分配为1链接性能值。增加的性能数字表示链接性能下降。
顺便说一下,如果您的目的是做到这一点:
引用:

基本上,做几乎与 nvidia-smi topo -m 相同的事情。

您将无法严格使用CUDA API调用来实现此目的。
供参考,这里是DGX-1的nvidia-smi topo -m输出和./topologyQuery输出:
# nvidia-smi topo -m
        GPU0    GPU1    GPU2    GPU3    GPU4    GPU5    GPU6    GPU7    CPU Affinity
GPU0     X      NV1     NV1     NV2     NV2     PHB     PHB     PHB     0-79
GPU1    NV1      X      NV2     NV1     PHB     NV2     PHB     PHB     0-79
GPU2    NV1     NV2      X      NV2     PHB     PHB     NV1     PHB     0-79
GPU3    NV2     NV1     NV2      X      PHB     PHB     PHB     NV1     0-79
GPU4    NV2     PHB     PHB     PHB      X      NV1     NV1     NV2     0-79
GPU5    PHB     NV2     PHB     PHB     NV1      X      NV2     NV1     0-79
GPU6    PHB     PHB     NV1     PHB     NV1     NV2      X      NV2     0-79
GPU7    PHB     PHB     PHB     NV1     NV2     NV1     NV2      X      0-79

Legend:

  X    = Self
  SYS  = Connection traversing PCIe as well as the SMP interconnect between NUMA nodes (e.g., QPI/UPI)
  NODE = Connection traversing PCIe as well as the interconnect between PCIe Host Bridges within a NUMA node
  PHB  = Connection traversing PCIe as well as a PCIe Host Bridge (typically the CPU)
  PXB  = Connection traversing multiple PCIe switches (without traversing the PCIe Host Bridge)
  PIX  = Connection traversing a single PCIe switch
  NV#  = Connection traversing a bonded set of # NVLinks
# ./topologyQuery
GPU0 <-> GPU1:
  * Atomic Supported: yes
  * Perf Rank: 1
GPU0 <-> GPU2:
  * Atomic Supported: yes
  * Perf Rank: 1
GPU0 <-> GPU3:
  * Atomic Supported: yes
  * Perf Rank: 0
GPU0 <-> GPU4:
  * Atomic Supported: yes
  * Perf Rank: 0
GPU1 <-> GPU0:
  * Atomic Supported: yes
  * Perf Rank: 1
GPU1 <-> GPU2:
  * Atomic Supported: yes
  * Perf Rank: 0
GPU1 <-> GPU3:
  * Atomic Supported: yes
  * Perf Rank: 1
GPU1 <-> GPU5:
  * Atomic Supported: yes
  * Perf Rank: 0
GPU2 <-> GPU0:
  * Atomic Supported: yes
  * Perf Rank: 1
GPU2 <-> GPU1:
  * Atomic Supported: yes
  * Perf Rank: 0
GPU2 <-> GPU3:
  * Atomic Supported: yes
  * Perf Rank: 0
GPU2 <-> GPU6:
  * Atomic Supported: yes
  * Perf Rank: 1
GPU3 <-> GPU0:
  * Atomic Supported: yes
  * Perf Rank: 0
GPU3 <-> GPU1:
  * Atomic Supported: yes
  * Perf Rank: 1
GPU3 <-> GPU2:
  * Atomic Supported: yes
  * Perf Rank: 0
GPU3 <-> GPU7:
  * Atomic Supported: yes
  * Perf Rank: 1
GPU4 <-> GPU0:
  * Atomic Supported: yes
  * Perf Rank: 0
GPU4 <-> GPU5:
  * Atomic Supported: yes
  * Perf Rank: 1
GPU4 <-> GPU6:
  * Atomic Supported: yes
  * Perf Rank: 1
GPU4 <-> GPU7:
  * Atomic Supported: yes
  * Perf Rank: 0
GPU5 <-> GPU1:
  * Atomic Supported: yes
  * Perf Rank: 0
GPU5 <-> GPU4:
  * Atomic Supported: yes
  * Perf Rank: 1
GPU5 <-> GPU6:
  * Atomic Supported: yes
  * Perf Rank: 0
GPU5 <-> GPU7:
  * Atomic Supported: yes
  * Perf Rank: 1
GPU6 <-> GPU2:
  * Atomic Supported: yes
  * Perf Rank: 1
GPU6 <-> GPU4:
  * Atomic Supported: yes
  * Perf Rank: 1
GPU6 <-> GPU5:
  * Atomic Supported: yes
  * Perf Rank: 0
GPU6 <-> GPU7:
  * Atomic Supported: yes
  * Perf Rank: 0
GPU7 <-> GPU3:
  * Atomic Supported: yes
  * Perf Rank: 1
GPU7 <-> GPU4:
  * Atomic Supported: yes
  * Perf Rank: 0
GPU7 <-> GPU5:
  * Atomic Supported: yes
  * Perf Rank: 1
GPU7 <-> GPU6:
  * Atomic Supported: yes
  * Perf Rank: 0
GPU0 <-> CPU:
  * Atomic Supported: no
GPU1 <-> CPU:
  * Atomic Supported: no
GPU2 <-> CPU:
  * Atomic Supported: no
GPU3 <-> CPU:
  * Atomic Supported: no
GPU4 <-> CPU:
  * Atomic Supported: no
GPU5 <-> CPU:
  * Atomic Supported: no
GPU6 <-> CPU:
  * Atomic Supported: no
GPU7 <-> CPU:
  * Atomic Supported: no

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接