【问题标题】:Processor/socket affinity in openMPI?openMPI 中的处理器/套接字关联?
【发布时间】:2013-07-10 09:40:30
【问题描述】:

我知道,openMPI 实现中有一些基本功能可以将不同进程映射到不同套接字的不同内核(如果系统有多个套接字)。

  1. --bind-to-socket(先到先得)
  2. --bysocket(循环,基于负载均衡)
  3. --npersocket N(给每个socket分配N个进程)
  4. --npersocket N --bysocket(为每个socket分配N个进程,但在循环的基础上)
  5. --bind-to-core(按顺序将一个进程绑定到每个内核)
  6. --bind-to-core --bysocket(为每个核心分配一个进程,但不要让任何套接字利用率低)
  7. --cpus-per-proc N(将进程绑定到多个内核)
  8. --rankfile(可以写出每个进程的偏好的完整描述)

我在一个有 8 个套接字(每个 10 个内核)的服务器上运行我的 openMPI 程序,并且由于多线程已打开,因此有 160 个内核可用。 我需要通过在套接字/内核和进程的不同组合上运行 openMPI 程序来进行分析。我希望在使用所有套接字并且代码正在处理一些数据传输的情况下,速度最慢,因为内存传输速度最快,以防两者该进程正在同一个套接字的核心上执行。

So my questions are follows,

  1. 进程和套接字之间的最坏/最佳情况映射是什么(每个进程都有一个睡眠持续时间和一个到根进程的数据传输)?

  2. 有没有办法打印正在执行进程的套接字名称和核心详细信息? (我会让我们知道,如果进程真的在套接字之间分配自己)

【问题讨论】:

    标签: mpi cpu core processor openmpi


    【解决方案1】:
    1. 这取决于很多因素,以至于不可能存在单一的“银弹”答案。这些因素包括计算强度(FLOPS/字节)以及本地数据量与进程之间传递的数据量之间的比率。它还取决于系统的架构。计算强度可以通过分析估计或使用 PAPI、Likwid 等分析工具进行测量。可以使用 lstopo 实用程序检查系统架构,该实用程序是 hwloc 库的一部分,它带有 Open MPI。不幸的是,lstopo 无法告诉您每个内存通道的速度以及 NUMA 节点之间的链接的速度/延迟。

    2. 是的,有:--report-bindings 使每个等级打印到其标准错误输出适用于它的亲和掩码。不同 Open MPI 版本的输出略有不同:

    Open MPI 1.5.x显示亲和力掩码的十六进制值:

    mpiexec --report-bindings --bind-to-core --bycore

    [hostname:00599] [[10634,0],0] odls:default:fork binding child [[10634,1],0] to cpus 0001
    [hostname:00599] [[10634,0],0] odls:default:fork binding child [[10634,1],1] to cpus 0002
    [hostname:00599] [[10634,0],0] odls:default:fork binding child [[10634,1],2] to cpus 0004
    [hostname:00599] [[10634,0],0] odls:default:fork binding child [[10634,1],3] to cpus 0008
    

    这表明等级 0 的关联掩码设置为 0001,这允许它仅在 CPU 0 上运行。 Rank 1 将其关联掩码设置为 0002,这允许它仅在 CPU 1 上运行。以此类推。

    mpiexec --report-bindings --bind-to-socket --bysocket

    [hostname:21302] [[30955,0],0] odls:default:fork binding child [[30955,1],0] to socket 0 cpus 003f
    [hostname:21302] [[30955,0],0] odls:default:fork binding child [[30955,1],1] to socket 1 cpus 0fc0
    [hostname:21302] [[30955,0],0] odls:default:fork binding child [[30955,1],2] to socket 0 cpus 003f
    [hostname:21302] [[30955,0],0] odls:default:fork binding child [[30955,1],3] to socket 1 cpus 0fc0
    

    在这种情况下,关联掩码在003f0fc0 之间交替。二进制中的003f0000000000111111,这样的关联掩码允许每个偶数秩在0 到5 的CPU 上执行。0fc00000111111000000,因此奇数秩只安排在5 到11 的CPU 上。

    Open MPI 1.6.x 改为使用更好的图形显示:

    mpiexec --report-bindings --bind-to-core --bycore

    [hostname:39646] MCW rank 0 bound to socket 0[core 0]: [B . . . . .][. . . . . .]
    [hostname:39646] MCW rank 1 bound to socket 0[core 1]: [. B . . . .][. . . . . .]
    [hostname:39646] MCW rank 2 bound to socket 0[core 2]: [. . B . . .][. . . . . .]
    [hostname:39646] MCW rank 3 bound to socket 0[core 3]: [. . . B . .][. . . . . .]
    

    mpiexec --report-bindings --bind-to-socket --bysocket

    [hostname:13888] MCW rank 0 bound to socket 0[core 0-5]: [B B B B B B][. . . . . .]
    [hostname:13888] MCW rank 1 bound to socket 1[core 0-5]: [. . . . . .][B B B B B B]
    [hostname:13888] MCW rank 2 bound to socket 0[core 0-5]: [B B B B B B][. . . . . .]
    [hostname:13888] MCW rank 3 bound to socket 1[core 0-5]: [. . . . . .][B B B B B B]
    

    每个插槽都以图形方式表示为一组方括号,每个核心由一个点表示。每个等级所绑定的核心由字母B 表示。进程只绑定到第一个硬件线程。

    Open MPI 1.7.x 有点冗长,也了解硬件线程:

    mpiexec --report-bindings --bind-to-core

    [hostname:28894] MCW rank 0 bound to socket 0[core 0[hwt 0-1]]: [BB/../../../../..][../../../../../..]
    [hostname:28894] MCW rank 1 bound to socket 0[core 1[hwt 0-1]]: [../BB/../../../..][../../../../../..]
    [hostname:28894] MCW rank 2 bound to socket 0[core 2[hwt 0-1]]: [../../BB/../../..][../../../../../..]
    [hostname:28894] MCW rank 3 bound to socket 0[core 3[hwt 0-1]]: [../../../BB/../..][../../../../../..]
    

    mpiexec --report-bindings --bind-to-socket

    [hostname:29807] MCW rank 0 bound to socket 0[core 0[hwt 0-1]], socket 0[core 1[hwt 0-1]], socket 0[core 2[hwt 0-1]], socket 0[core 3[hwt 0-1]], socket 0[core 4[hwt 0-1]], socket 0[core 5[hwt 0-1]]: [BB/BB/BB/BB/BB/BB][../../../../../..]
    [hostname:29807] MCW rank 1 bound to socket 1[core 6[hwt 0-1]], socket 1[core 7[hwt 0-1]], socket 1[core 8[hwt 0-1]], socket 1[core 9[hwt 0-1]], socket 1[core 10[hwt 0-1]], socket 1[core 11[hwt 0-1]]: [../../../../../..][BB/BB/BB/BB/BB/BB]
    [hostname:29807] MCW rank 2 bound to socket 0[core 0[hwt 0-1]], socket 0[core 1[hwt 0-1]], socket 0[core 2[hwt 0-1]], socket 0[core 3[hwt 0-1]], socket 0[core 4[hwt 0-1]], socket 0[core 5[hwt 0-1]]: [BB/BB/BB/BB/BB/BB][../../../../../..]
    [hostname:29807] MCW rank 3 bound to socket 1[core 6[hwt 0-1]], socket 1[core 7[hwt 0-1]], socket 1[core 8[hwt 0-1]], socket 1[core 9[hwt 0-1]], socket 1[core 10[hwt 0-1]], socket 1[core 11[hwt 0-1]]: [../../../../../..][BB/BB/BB/BB/BB/BB]
    

    Open MPI 1.7.x 还将--bycore--bysocket 选项替换为更通用的--rank-by <policy> 选项。

    【讨论】:

    • --report-bindings 本身是否会在 cmd 上打印一些内容,或者如何进一步使用来获取进程使用的实际绑定?它没有为我打印任何额外内容!
    • 它使每个等级打印其与标准错误输出的绑定。
    • 即使在使用 this 将其重定向到 stdout 之后,我也没有在 stderr 上得到任何东西;字符缓冲区[BUFSIZ]; setbuf(stderr, buf);
    • @AnkurGautam,我已经用--report-bindings 的示例输出更新了答案。
    • 非常感谢!你总是尽量不留下进一步的问题。但我仍然无法弄清楚,如何将标准错误(因为绑定将在此处显示)重定向到标准输出?
    【解决方案2】:

    1。 如果每个节点和根节点之间的通信相等,并且没有其他通信模式,那么通信不会影响特定进程->套接字映射的性能。 (这是假设套接字之间的常规对称互连拓扑。)否则,您通常会尝试将具有大量通信的进程对放置在通信拓扑中彼此靠近。在共享内存系统上使用 MPI 可能不相关,但在集群上肯定是相关的。

    但是,负载平衡也可能会影响映射的性能。如果某些进程等待消息/屏障,则该套接字上的其他内核可能能够利用更高的涡轮频率。这在很大程度上取决于应用程序的运行时行为。仅由睡眠和传输组成的应用程序没有任何意义。

    1. 您可以使用 libnuma / sched_getaffinity 手动确认您的进程固定。

    有许多性能分析工具有助于回答您的问题。例如,OpenMPI 带有VampirTrace,它会生成包含有关 MPI 通信等信息的跟踪。您可以通过Vampir查看。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-20
      • 1970-01-01
      • 2018-11-20
      • 1970-01-01
      • 1970-01-01
      • 2017-12-31
      • 1970-01-01
      • 2017-12-04
      相关资源
      最近更新 更多