【问题标题】:When MPI_Send doesn't block当 MPI_Send 不阻塞时
【发布时间】:2017-06-20 18:53:41
【问题描述】:

我使用了一些实现手动 MPI 广播的代码,基本上是一个将整数从根单播到所有其他节点的演示。当然,单播到多个节点的效率不如MPI_Bcast(),但我只是想检查一下事情是如何工作的。

#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>

void my_bcast(void* data, int count, MPI::Datatype datatype, int root, MPI::Intracomm communicator) {
    int world_size = communicator.Get_size();
    int world_rank = communicator.Get_rank();

    if (world_rank == root) {
        // If we are the root process, send our data to everyone
        int i;
        for (i = 0; i < world_size; i++) {
            if (i != world_rank) {
                communicator.Send(data, count, datatype, i, 0);
            }
        }
    } else {
        // If we are a receiver process, receive the data from the root
        communicator.Recv(data, count, datatype, root, 0);
    }
}

int main(int argc, char** argv) {
    MPI::Init();

    int world_rank = MPI::COMM_WORLD.Get_rank();

    int data;
    if (world_rank == 0) {
        data = 100;
        printf("Process 0 broadcasting data %d\n", data);
        my_bcast(&data, 1, MPI::INT, 0, MPI::COMM_WORLD);
    } else {
        my_bcast(&data, 1, MPI::INT, 0, MPI::COMM_WORLD);
        printf("Process %d received data %d from root process\n", world_rank, data);
    }

    MPI::Finalize();
}

我注意到的是,如果我删除根不发送给自己的检查,

if (i != world_rank) {
...
}

程序仍然可以工作并且不会阻塞,而MPI_Send() 的默认行为应该是阻塞的,即等到另一端接收到数据。但是MPI_Recv() 永远不会被根调用。有人可以解释为什么会这样吗?

我使用以下命令从根目录运行代码(集群设置在 Amazon EC2 上并使用 NFS 作为节点之间的共享存储,并且所有机器都安装了 Open MPI 1.10.2)

mpirun -mca btl ^openib -mca plm_rsh_no_tree_spawn 1 /EC2_NFS/my_bcast

C文件编译用

mpic++ my_bcast.c

mpic++ 版本是 5.4.0。

代码取自www.mpitutorial.com

【问题讨论】:

    标签: amazon-ec2 mpi send broadcast openmpi


    【解决方案1】:

    您将 blocking 误认为 同步 行为。阻塞意味着在操作完成之前调用不会返回。一旦提供的缓冲区可以被程序重用,标准的发送操作 (MPI_Send) 就完成了。这意味着消息要么完全传输到接收者,要么由 MPI 库在内部存储以供以后传递(缓冲发送)。缓冲行为是特定于实现的,但大多数库将缓冲单个整数大小的消息。使用 MPI_Ssend(或 C++ 等效项)强制同步模式让您的程序挂起。

    请注意,C++ MPI 绑定不再是标准的一部分,不应用于新软件的开发。请改用 C 绑定 MPI_Blabla

    【讨论】:

    • C++ MPI 绑定的另一种替代方法是使用 boostMPI。 boostMPI 不是标准的一部分,但由于一些开发人员喜欢它,我认为值得一提。
    • Boost.MPI 在操作方面远远落后于当前标准,但就其实现而言,它确实是围绕 MPI 功能的一个有价值的 OO 包装器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-11
    • 1970-01-01
    • 2023-03-17
    • 2014-05-25
    • 2023-01-10
    • 1970-01-01
    • 2015-04-27
    相关资源
    最近更新 更多