MPI_Isend:如何在收到数据之前确保数据安全?

MPI_Isend: how to keep data safe until they're received?

我要使用 MPI_Isend 发送很多消息,但我不确定如何确保我的数据在收到之前是安全的,同时,不要用完所有可用的内存.

目前,我正在做这样的事情:

vector<int*> outbox;
vector<MPI_Request> stats;

void run()
{
   while (!done()) 
   {
       //some magic
       //...

       sendMsg(rand(), getRecipRank());
  }
}

void sendMsg(int n, int recipRank)
{
    //Need to gen n random integers and send it to proc with rank recipRank
    //Can't block until the numbers are reveived. 
    //So how do I make sure these numbers are safe until then?


    int* data = (int*)malloc(sizeof(int) * n);
    //fill the data array with random numbers here

    MPI_Request req;
    MPI_Isend(data, n, MPI_INT, recipRank, 0, MPI_COMM_WORLD, &req);

    //Keeping the pointer to the array to free it later
    outbox.push_back(data); //Does this help keep the data safe until they're received?
    stats.push_back(req);
}

然后我有另一个函数偶尔会通过 stats 向量来检查发送状态。如果完成,则函数释放 outbox.

中的请求和相应数组

我已经用少量消息对此进行了测试,它似乎有效,但我不确定它是否会 ALWAYS 有效,或者我只是很幸运。

看起来不错!如果您使用 malloc 分配内存,除了您之外,没有人会弄乱它。既然你不乱来,那就安全了。

这是一种很好的模式,可以通过使用更多内存来交织计算和通信。如果您想限制内存使用,您可以为向量施加最大长度 outbox 并在达到该长度时开始使用阻塞发送。

澄清一下:您的数据不是 "safer",因为您将其推入向量 outbox,即使不这样做也是安全的。您将其推入矢量以便稍后释放它。

这很好用,但你甚至不需要求助于 C-malloc

您可以安全地使用 C++ 构造,例如:

  • new[] 中的指针 std::vector<int*>
  • std::vector<std::unique_ptr<int[]>>(我更喜欢你的情况)
  • std::vector::data() 个向量中的向量。为此,请确保在请求完成之前不要在提供所调用内存的向量上调用任何非常量方法。

使用 std::vector<int[10]> outboxstd::vector<std::array<int, 10>> outbox 是安全的,因为此内存将直接在发件箱向量中引用,可能会重新分配(调整大小)进一步调用 push_back。但这只对编译时已知的 n 重要。 std::vector<std::unique_ptr<std::array<int, 10>>> 会好的。