1

我正在尝试使用 MPI 发送 std::vector 。当向量很小时,这可以正常工作,但当向量很大时(向量中超过 ~15k 双倍)就不起作用。当尝试发送一个具有 20k 双精度的向量时,程序只是坐在那里,CPU 为 100%。

这是一个最小的例子

#include <vector>
#include <mpi.h>

using namespace std;

vector<double> send_and_receive(vector<double> &local_data, int n, int numprocs, int my_rank) {
    MPI_Send(&local_data[0], n, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);

    if (my_rank == 0) {
        vector<double> global_data(numprocs*n);
        vector<double> temp(n);
        for (int rank = 0; rank < numprocs; rank++) {
            MPI_Recv(&temp[0], n, MPI_DOUBLE, rank, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
            for (int i = 0; i < n; i++) {
                global_data[rank*n + i] = temp[i];
            }
        }
        return global_data;
    }
    return vector<double>();
}

int main(int args, char *argv[]) {
    int my_rank, numprocs;
    // MPI initialization
    MPI_Init (&args, &argv);
    MPI_Comm_rank (MPI_COMM_WORLD, &my_rank);
    MPI_Comm_size (MPI_COMM_WORLD, &numprocs);

    int n = 15000;
    vector<double> local_data(n);

    for (int i = 0; i < n; i++) {
        local_data[i] = n*my_rank + i;
    }

    vector<double> global_data = send_and_receive(local_data, n, numprocs, my_rank);

    MPI_Finalize();

    return 0;
}

我编译使用

mpic++ main.cpp

并使用

mpirun -n 2 a.out

当我运行n = 15000程序成功完成,但n = 17000n = 20000它永远不会完成,并且两个 CPU 处于 100% 的位置,直到我强制关闭程序。

有谁知道是什么问题?

4

1 回答 1

2

MPI_Send是一个有趣的电话。如果有足够的内部缓冲区来存储输入,它可能会返回 - 它做出的唯一保证是 MPI 将不再需要输入缓冲区。但是,如果没有足够的内部缓冲区空间,调用将阻塞,直到相反的MPI_Recv调用开始接收数据。看看这是怎么回事?MPI_Send由于缓冲区空间不足,两个进程都会发布该块。在调试这样的问题时,它有助于替换MPI_SendMPI_Ssend.

您可能的解决方案是:

  • 使用缓冲发送,MPI_Bsend.
  • 采用MPI_Sendrecv
  • 交替发送/接收对,以便每个发送都有一个匹配的接收(例如奇数proc发送,偶数recv,反之亦然)。
  • 使用非阻塞发送,MPI_Isend

http://www.netlib.org/utk/papers/mpi-book/node39.html

于 2013-09-11T16:35:44.313 回答