2

我有一个非常简单的代码,一个数据分解问题,其中在一个循环中,每个进程在每个循环之前和之后向队列发送两条大消息。我在 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=bunch

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

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

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

非常感谢。

4

2 回答 2

5

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

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

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

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

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

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

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

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

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

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

于 2012-12-20T13:00:40.210 回答
0

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

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

来自MPICH 环境变量

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

于 2015-11-07T02:42:12.527 回答