【问题标题】:Figuring out GPU links topology programmatically with CUDA使用 CUDA 以编程方式计算 GPU 链接拓扑
【发布时间】:2019-09-18 00:05:59
【问题描述】:

我正在尝试找出 GPU 之间的链路拓扑。 基本上,和nvidia-smi topo -m 做的差不多。

我找到了一个 CUDA 示例 topologyQuery,它基本上调用 cudaDeviceGetP2PAttribute(&perfRank, cudaDevP2PAttrPerformanceRank, device1, device2) 用于每对 GPU。

运行这个例子的结果(我稍微修改了输出表示)让我很困惑(在与同一台机器上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 排名第一?为什么 PHB 排名为 0? 我是不是误解了cudaDevP2PAttrPerformanceRank查询的目的?

【问题讨论】:

    标签: cuda gpu nvidia multi-gpu


    【解决方案1】:

    我不知道您正在测试什么样的系统(它看起来很像 DGX-1 的输出)。

    关于这个问题:

    为什么 PHB 排名为 0?

    如果您运行原始的 topologyQuery 示例代码,您会看到(至少在类似 DGX-1 的系统上)它不会打印出每个 GPU 对的性能排名。据我所知,它不会打印出PHB 所在位置的性能排名。如果您研究原始代码,原因很明显:这些对组合不支持 P2P。但是,在这些情况下,您的代码似乎打印出一个零。所以我想说,与原始 topologyQuery 代码相比,这是您的代码中的一个缺陷,它导致了这个问题和您的误解。 PHB 没有被原始代码分配到 0 级。但是您修改后的代码可以做到这一点。那就由你来回答吧。

    为什么 NV1 排名第一?

    关于其余部分,NV2 连接意味着这 2 个 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-14
      • 2010-09-16
      • 1970-01-01
      • 2012-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-16
      相关资源
      最近更新 更多