【问题标题】:What exactly happens when we use mpi_send/receive functions?当我们使用 mpi_send/receive 函数时究竟会发生什么?
【发布时间】:2012-06-06 17:17:39
【问题描述】:

当我们使用mpi_send/receive 函数时会发生什么?我的意思是这种通信是通过我们希望发送和接收的变量的值或地址完成的(例如,进程 0 想要将变量“a”发送到进程 1。进程 0 究竟发送变量“a”的值或地址“一个”)。当我们使用派生数据类型进行通信时会发生什么?

【问题讨论】:

    标签: c++ mpi


    【解决方案1】:

    幕后发生了相当多的魔术。


    首先,有意外消息队列。当发送者在接收者调用MPI_Recv 之前调用MPI_Send 时,MPI 不知道消息在接收者的内存中的哪个位置。此时可能会发生两件事。如果消息很短,则将其复制到接收方的临时缓冲区。当接收者调用MPI_Recv 时,它首先检查匹配的消息是否已经到达,如果已经到达,则将数据复制到最终目的地。如果不是,则有关目标缓冲区的信息将存储在队列中,以便在消息到达时匹配MPI_Recv。可以使用MPI_Probe 检查意外队列。

    如果消息长于某个阈值,则复制它会花费很长时间。相反,发送方和接收方使用某种会合协议进行握手,以确保目标在消息发出之前已准备好接收消息。这对于像 InfiniBand 这样的高速网络尤其重要。


    如果通信队列在同一台机器上,通常数据传输是通过共享内存进行的。因为 MPI rank 是独立的进程,所以它们不能访问彼此的内存。相反,同一节点上的 MPI 进程设置了一个共享内存区域并使用它来传输消息。因此发送消息涉及复制数据两次:发送方将其复制到共享缓冲区中,接收方将其复制到自己的地址空间中。这有一个例外。如果 MPI 库配置为使用像 KNEM 这样的内核模块,则可以将消息直接复制到 OS 内核中的目标。然而,这样的拷贝会招致系统调用的惩罚。通过内核进行复制通常只对大消息是值得的。 Catamount 等专门的 HPC 操作系统可以改变这些规则。


    集体操作可以在发送/接收方面实现,也可以有一个完全独立的优化实现。为集体操作实现几种算法是很常见的。 MPI 库在运行时根据消息的大小和通信器决定使用哪一个以获得最佳性能。


    一个好的 MPI 实现会非常努力地传输 派生数据类型,而不会创建额外的副本。它将找出数据类型中的哪些内存区域是连续的,并单独复制它们。但是,在某些情况下,MPI 会回退到在后台使用 MPI_Pack 以使消息连续,然后传输并解包。

    【讨论】:

    • 正如我所读到的,Infiniband 确实没有使用意外队列(在低级别),而 Myrinet 确实如此。你能评论一下吗?
    • InfiniBand 没有提供意外的队列,但是基于 IB 的 MPI 实现提供了自己的队列。 Myrinet MX 确实提供了一个内置的意外队列。如果消息到达没有发布缓冲区的 IB 接收队列,则传输失败,并且 Receiver-Not-Ready 数据包被发送给发送者。发送者可以重试传输。这显然很慢,因此 MPI 实现使 RQ 充满了意外消息的缓冲区。 Myrinet MX 自己处理这个问题。无论哪种方式,意外消息都被缓冲在与目标不同的地方,并且必须被复制。
    【解决方案2】:

    就应用系统程序员而言,这些操作发送和接收数据,而不是数据地址。 MPI 进程不共享地址空间,因此进程 0 上的地址对于进程 1 上的操作毫无意义 - 如果进程 1 想要进程 0 上的地址处的数据,它必须从进程 0 中获取它。我不认为MPI-2 带来的单面通信对这种情况产生了重大影响。

    从 MPI 库开发人员的角度来看,幕后发生的事情可能会有所不同,并且肯定会依赖于实现。例如,如果您在共享内存机器上使用编写良好的 MPI 库,那么可以,它可能只是通过发送指向系统周围地址位置的指针来实现消息传递。但这是一个极端案例,这些天很少见。

    【讨论】:

      【解决方案3】:

      mpi_send 要求您将地址提供给保存要发送的数据的内存。只有当它被保存以供您重新使用该内存时才会返回(这可以通过非阻塞通信来避免)。

      同样,mpi_recv 要求您提供足够的内存地址,它可以将要接收的数据复制到该地址。仅当数据已被接收到该缓冲区时才会返回。

      MPI 如何做到这一点是另一回事,您不必担心编写一个有效的 MPI 程序(但可能是编写一个高效的程序)。

      【讨论】:

        猜你喜欢
        • 2023-04-01
        • 1970-01-01
        • 2023-03-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多