【问题标题】:Overlapping communications with computations in MPI (mvapich2) for large messages与 MPI (mvapich2) 中的计算重叠通信以处理大型消息
【发布时间】:2012-12-07 11:30:29
【问题描述】:

我有一个非常简单的代码,一个数据分解问题,其中在一个循环中,每个进程在每个循环中向自身前后的队列发送两条大消息。我在 SMP 节点集群(AMD Magny 内核,每个节点 32 个内核,每个插槽 8 个内核)中运行此代码。有一段时间我正在优化这段代码。我使用 pgprof 和 tau 进行分析,在我看来瓶颈是通信。我试图将通信与我的代码中的计算重叠,但是看起来实际的通信在计算完成时开始:(

我在就绪模式 (MPI_Rsend_init) 下使用持久通信,并在 MPI_Start_all 和 MPI_Wait_all 之间完成大量计算。代码如下所示:

void main(int argc, char *argv[])
{
  some definitions;
  some initializations;

  MPI_Init(&argc, &argv);

  MPI_Rsend_init( channel to the rank before );
  MPI_Rsend_init( channel to the rank after );
  MPI_Recv_init( channel to the rank before );
  MPI_Recv_init( channel to the rank after );

  for (timestep=0; temstep<Time; timestep++)
  {
    prepare data for send;
    MPI_Start_all();

    do computations;

    MPI_Wait_all();

    do work on the received data;
  }
  MPI_Finalize();
}

不幸的是,实际的数据传输直到计算完成才开始,我不明白为什么。该网络使用 QDR InfiniBand 互连和 mvapich2。每条消息大小为 23MB(总共发送 46MB 消息)。我试图将消息传递更改为急切模式,因为系统中的内存足够大。我在我的作业脚本中使用以下标志: MV2_SMP_EAGERSIZE=46M
MV2_CPU_BINDING_LEVEL=socket
MV2_CPU_BINDING_POLICY=一堆

这给了我大约 8% 的改进,这可能是因为 SMP 节点内的等级更好地放置了,但是仍然存在通信问题。我的问题是为什么我不能有效地将通信与计算重叠?是否有任何我应该使用的标志并且我错过了它?我知道有些不对劲,但我所做的一切都还不够。

按照 SMP 节点内的等级顺序,节点之间的实际消息大小也是 46MB (2x23MB),并且等级处于循环中。你能帮我么?要查看其他用户使用的标志,我检查了 /etc/mvapich2.conf 但它是空的。

我应该使用其他方法吗?你认为单方面的沟通会带来更好的表现吗?我觉得有一个标志或我不知道的东西。

非常感谢。

【问题讨论】:

    标签: c performance mpi


    【解决方案1】:

    在 MPI 中有一种叫做操作进度的东西。该标准允许非阻塞操作仅在进行正确的测试/等待调用后才进行到完成:

    非阻塞 send start 调用会启动发送操作,但不会完成它。发送开始调用可以在消息被复制出发送缓冲区之前返回。需要一个单独的 send complete 调用来完成通信,即验证数据是否已从发送缓冲区中复制出来。 使用合适的硬件,数据从发送方内存的传输可以与发送方在发送开始之后和完成之前完成的计算同时进行。类似地,非阻塞接收开始调用 启动接收操作,但不完成。该调用可以在消息存储到接收缓冲区之前返回。需要一个单独的 receive complete 调用来完成接收操作并验证数据是否已被接收到接收缓冲区中。 使用合适的硬件,数据到接收器内存的传输可以与在接收开始之后和完成之前完成的计算同时进行。

    粗体中的单词在标准文本中也加粗;强调由我添加)

    虽然此文本来自关于非阻塞通信的部分(MPI-3.0 的第 3.7 节;该文本与 MPI-2.2 中的文本完全相同),但它也适用于持久通信请求。

    我没有使用过 MVAPICH2,但我可以谈谈在 Open MPI 中是如何实现的。每当启动非阻塞操作或启动持久通信请求时,该操作都会被添加到待处理操作队列中,然后以两种可能的方式之一进行:

    • 如果 Open MPI 是在没有异步进程线程的情况下编译的,则未完成的操作会在每次调用发送/接收或某些等待/测试操作时进行;
    • 如果 Open MPI 是使用异步进程线程编译的,即使没有进行进一步的通信调用,操作也会在后台进行。

    默认行为是不启用异步进程线程,因为这样做会以某种方式增加操作的延迟。

    目前无法从此处访问 MVAPICH 站点,但之前我看到功能列表中提到了异步进度。可能这就是您应该开始的地方 - 寻找启用它的方法。

    还要注意MV2_SMP_EAGERSIZE控制共享内存协议的eager消息大小并且不影响InfiniBand协议,即它只能改善驻留在同一集群节点上的进程之间的通信。

    顺便说一句,不能保证接收操作会在相邻队列中的就绪发送操作之前启动,因此它们可能无法按预期运行,因为时间排序在那里非常重要。

    【讨论】:

    • 谢谢大佬,这真的很有帮助,我对它进行了完整的搜索,但仍然没有成功,无论如何谢谢
    【解决方案2】:

    对于 MPICH,您可以在运行 mpiexec/mpirun 时设置 MPICH_ASYNC_PROGRESS=1 环境变量。这将产生一个执行“异步进度”的后台进程。

    MPICH_ASYNC_PROGRESS - 启动备用线程以提供 异步进度。这改进了进度语义 所有 MPI 操作,包括点对点、集体、 单向操作和 I/O。设置这个变量会 将线程安全级别提高到 MPI_THREAD_MULTIPLE。虽然这提高了进度 语义,它可能会导致少量的性能 常规 MPI 操作的开销。

    来自MPICH Environment Variables

    我已经用 MPICH-3.1.4 在我的集群上进行了测试,它成功了!我相信 MVAPICH 也会起作用。

    【讨论】:

      猜你喜欢
      • 2021-05-22
      • 2018-10-09
      • 1970-01-01
      • 1970-01-01
      • 2016-09-28
      • 2010-11-11
      • 2014-07-11
      • 2014-04-28
      • 1970-01-01
      相关资源
      最近更新 更多