何时在MPI中发送和接收消息时使用标签?

时间:2015-07-13 14:52:31

标签: mpi

我不确定何时必须为MPI发送,接听电话中的标记字段使用不同的数字。我读过this,但我无法理解。

  

有时,A可能需要发送许多不同的内容   到B的消息类型。而不是B必须通过额外的   用于区分所有这些消息的措施,MPI允许发送者和   接收者也用消息指定消息ID(称为   标签)。当进程B仅请求具有特定标记的消息时   数字,具有不同标签的消息将由网络缓冲   直到B为他们做好准备。

我是否必须使用标签,例如,当我在流程A中有多个调用“isend”(带有不同的标签)并且在流程B中只有1个调用“ireceive”时?

2 个答案:

答案 0 :(得分:12)

消息标签是可选的。您可以为它们使用任意整数值,并使用您喜欢的任何语义,并且对您有用。

与您建议的一样,标记可用于区分由不同类型(MPI_INTEGERMPI_REALMPI_BYTE等组成的消息。您还可以使用标记添加有关数据实际代表内容的一些信息(如果您有n x n矩阵,则发送此矩阵行的消息将包含n值,以及发送该矩阵列的消息;但是,您可能希望以不同方式处理行和列数据)。

请注意,接收操作必须与要接收的消息的标记相匹配。但是,这并不意味着您必须指定相同的标记,也可以使用通配符MPI_ANY_TAG作为消息标记;然后,接收操作将匹配任意消息标记。您可以在MPI_Probe的帮助下找出发件人使用的标记。

答案 1 :(得分:10)

一般来说,我倾向于避开它们。您无需使用标签。如果在解析消息之前需要获取消息大小,则可以使用MPI_Probe。这样您就可以发送不同的消息而不是指定标签。我通常使用标签,因为MPI_Recv要求您在获取数据之前知道邮件大小。如果您有不同的大小和类型,标记可以帮助您通过让多个线程或进程监听不同的子集来区分它们。标签1可以表示类型为X的消息,而标签2可以是类型为Y的消息。此外,它还使您能够拥有多个通信“通道”,而无需执行创建唯一通信器和组的工作。

#include <mpi.h>
#include <iostream>

using namespace std;

int main( int argc, char* argv[] )
{
    // Init MPI
    MPI_Init( &argc, &argv);

    // Get the rank and size
    int rank, size;
    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
    MPI_Comm_size( MPI_COMM_WORLD, &size );

    // If Master
    if( rank == 0 ){

        char* message_r1 = "Hello Rank 1";
        char* message_r2 = "Hello Rank 2";

        // Send a message over tag 0
        MPI_Send( message_r1, 13, MPI_CHAR, 1, 0, MPI_COMM_WORLD );

        // Send a message over tag 1
        MPI_Send( message_r2, 13, MPI_CHAR, 2, 1, MPI_COMM_WORLD );


    }
    else{

        // Buffer
        char buffer[256];
        MPI_Status status;

        // Wait for your own message
        MPI_Recv( buffer, 13, MPI_CHAR, 0, rank-1, MPI_COMM_WORLD, &status );

        cout << "Rank: " << rank << ", Message: " << buffer << std::endl;

    }

    // Finalize MPI
    MPI_Finalize();

}