openMPI中的处理器/套接字亲和性?

10
我知道,在openMPI实现中有一些基本函数,用于将不同进程映射到不同的插槽(如果系统有多个插槽)。
  1. --bind-to-socket(先到先得)
  2. --bysocket(循环方式,基于负载平衡)
  3. --npersocket N(将N个进程分配给每个插槽)
  4. --npersocket N --bysocket(将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. 有没有办法打印出进程正在执行的套接字名称和核心详细信息?(我将利用它来了解进程是否真正在套接字之间分配)

2个回答

12
  • 因素太多了,不存在一个单一的“万能方案”。这些因素包括计算强度(FLOPS/字节)和本地数据量与传递给进程之间数据量之比。同时它也取决于系统的架构。计算强度可以通过分析估算或使用像PAPI、Likwid等配置工具进行测量。使用Open MPI附带的hwloc库中的lstopo实用程序可以检查系统的体系结构。不幸的是,lstopo无法告诉您每个内存通道有多快,以及NUMA节点之间的链接速度/延迟。
  • --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上运行。排名为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,因此奇数排名只安排在 CPU 5 到 11 上。 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也用更通用的--rank-by <policy>选项替换了--bycore--bysocket选项。


即使使用以下代码将stderr重定向到stdout,我仍然无法在stderr上获取任何内容:char buf[BUFSIZ]; setbuf(stderr, buf); - Ankur Gautam
非常感谢!您总是尽力回答所有问题,但我仍然无法弄清楚如何将stderr(因为绑定将在此处显示)重定向到stdout? - Ankur Gautam
当我使用2>&1时,我甚至无法看到标准输出(stdout),即代码中的常规cout打印。 - Ankur Gautam
mpiexec和mpirun有区别吗?我以为它们是一样的。 - Ankur Gautam
2>&1 也无法与 mpiexec 正常工作 :( (终端上没有输出) - Ankur Gautam
显示剩余8条评论

2

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

然而,负载平衡也可能会影响映射的性能。如果某些进程等待消息/屏障,则该套接字上的其他核心可能能够利用更高的Turbo频率。这严重依赖于应用程序的运行时行为。仅由休眠和传输组成的应用程序实际上没有意义。

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

有许多性能分析工具可帮助回答您的问题。例如,OpenMPI配备了VampirTrace,它生成包含MPI通信和更多信息的跟踪。您可以使用Vampir查看。


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