簡體   English   中英

一個不安全的 MPI 非阻塞通信示例?

[英]A not safe MPI non-blocking communication example?

我正在我的程序中實現 MPI 非阻塞通信。 我在MPI_Isend man_page上看到,它說:

非阻塞發送調用表明系統可能開始從發送緩沖區復制數據。 在調用非阻塞發送操作后,發送方不應修改發送緩沖區的任何部分,直到發送完成。

我的代碼是這樣工作的:

// send messages
if(s > 0){

    MPI_Requests s_requests[s];
    MPI_Status   s_status[s];

    for(int i = 0; i < s; ++i){

        // some code to form the message to send
        std::vector<doubel> send_info;

        // non-blocking send
        MPI_Isend(&send_info[0], ..., s_requests[i]);
    }

    MPI_Waitall(s, s_requests, s_status);
}

// recv info
if(n > 0){    // s and n will match

    for(int i = 0; i < n; ++i){

        MPI_Status status;

        // allocate the space to recv info
        std::vector<double> recv_info;

        MPI_Recv(&recv_info[0], ..., status)
    }

}


我的問題是:我是否修改了發送緩沖區,因為它們位於內部大括號中(循環結束后send_info向量被殺死)? 因此,這不是一種安全的通信方式嗎? 雖然我的程序現在運行良好,但我仍然被懷疑。 感謝你的回復。

在這個例子中我想強調兩點。

第一個是我質疑的問題:發送緩沖區在MPI_Waitall之前被修改。 原因就是吉爾斯所說的。 並且解決方案可以在for loop之前分配一個大緩沖區,並在循環完成后使用MPI_Waitall或將MPI_Wait放入循環中。 但后一種在性能意義上相當於使用MPI_Send

但是,我發現如果你只是轉移到阻塞發送和接收,這樣的通信方案可能會導致死鎖。 它類似於經典的死鎖:

if (rank == 0) {
      MPI_Send(..., 1, tag, MPI_COMM_WORLD);
      MPI_Recv(..., 1, tag, MPI_COMM_WORLD, &status);
 } else if (rank == 1) {
      MPI_Send(..., 0, tag, MPI_COMM_WORLD);
      MPI_Recv(..., 0, tag, MPI_COMM_WORLD, &status);
 }

可以在這里找到解釋。

我的程序可能會導致類似的情況:所有的處理器都調用MPI_Send然后這是一個死鎖。

所以我的解決方案是使用大緩沖區並堅持非阻塞通信方案。

#include <vector>
#include <unordered_map>

// send messages
if(s > 0){

    MPI_Requests s_requests[s];
    MPI_Status   s_status[s];

    std::unordered_map<int, std::vector<double>> send_info;

    for(int i = 0; i < s; ++i){


        // some code to form the message to send
        send_info[i] = std::vector<double> ();

        // non-blocking send
        MPI_Isend(&send_info[i][0], ..., s_requests[i]);
    }

    MPI_Waitall(s, s_requests, s_status);
}

// recv info
if(n > 0){    // s and n will match

    for(int i = 0; i < n; ++i){

        MPI_Status status;

        // allocate the space to recv info
        std::vector<double> recv_info;

        MPI_Recv(&recv_info[0], ..., status)
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM