搜索/等待在MS-MPI任何传输 [英] Search/wait for any transmission in MS-MPI

查看:121
本文介绍了搜索/等待在MS-MPI任何传输的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个主 - 从局面。我怎样才能使在传送给他发个消息非阻塞的方式主进程搜索。如果在搜索的点没有上发射掌握的消息,它会继续反复。然而,如果有发送给他的消息,则处理该消息并不是继续迭代。看到里面/注释* /

  INT主(INT ARGC,CHAR *的argv [])
{
    INT numprocs,
        秩;    MPI_Request请求;
    MPI_Status状态;    MPI_INIT(安培; ARGC,&安培; argv的);
    MPI_Comm_rank(MPI_COMM_WORLD,&安培;等级);
    MPI_Comm_size(MPI_COMM_WORLD,&安培; numprocs);
    如果(排名== 0)//搜索过程
    {
        的for(int i = 0; I< 4000000;我++)
        {
            //做一些东西在这里;什么都无所谓            / *看看是否有任何消息已在这一点上已经传染给我
             不受阻塞的进程;如果此时它正好是
             传播,做一些比继续为iternations;
             或者只是继续与迭代,也许下一次会
             有它发送我做一些事情的消息* /
        }
    }
    其他
    {
        INT标志= 1;
        而(标志)
        {
            //有所作为,在某些时候改变标志
        }        //发送带有等级0来处理和没有得到困在这里
        MPI_Isend(12,1,MPI_INT,0,100,MPI_COMM_WORLD,&安培;要求);        //一些其他的东西做        //等待消息要发送
        MPI_WAIT(安培;请求和放大器;状态);
    }    MPI_Finalize();
    返回0;
}


解决方案

有关信息提供无阻塞测试使用 MPI_Iprobe 呼叫完成。在你的情况下,它看起来像:

  INT可用;
MPI_Status状态;如果(排名== 0)//搜索过程
{
    的for(int i = 0; I< 4000000;我++)
    {
        //做一些东西在这里;什么都无所谓        / *看看是否有任何消息已在这一点上已经传染给我
         不受阻塞的进程;如果此时它正好是
         传播,做一些比继续为iternations;
         或者只是继续与迭代,也许下一次会
         有它发送我做一些事情的消息* /        //标签值100的发送操作中使用的值相匹配
        MPI_Iprobe(MPI_ANY_SOURCE,100,MPI_COMM_WORLD,&安培;可用,&安培;状态);
        如果可供使用的话)
        {
            //消息源排名现已在status.MPI_SOURCE可用
            //收到消息
            MPI_RECV(...,status.MPI_SOURCE,status.MPI_TAG,MPI_COMM_WORLD,&安培;状态);
        }
    }
}

MPI_ANY_SOURCE 作为通配符等级,即,它指示 MPI_Irecv 来检查任何来源的消息。如果相应的发送被张贴,那么可用将被设置为true,否则将被设置为false。消息的实际源也写入 MPI_SOURCE 的状态对象的领域。如果可用标记表示匹配信息的可用性,应该再以收到后的接收操作。重要的是秩和标记在接收操作中明确指定,否则不同的消息可以得到接收的,而不是

您也可以使用持久连接。这些行为非常象具有使得它们可以重新多次的重要区别非阻塞操作。同样的code。与持久连接看起来像:

 如果(排名== 0)//搜索过程
{
    MPI_Request REQ;
    MPI_Status状态;
    INT完成;    // prepare持久连接请求
    MPI_Recv_init(缓冲,buf_size,buf_type,
                  MPI_ANY_SOURCE,100,MPI_COMM_WORLD,&安培; REQ);
    //使请求有效,
    MPI_Start(安培; REQ);    的for(int i = 0; I< 4000000;我++)
    {
        //做一些东西在这里;什么都无所谓        / *看看是否有任何消息已在这一点上已经传染给我
         不受阻塞的进程;如果此时它正好是
         传播,做一些比继续为iternations;
         或者只是继续与迭代,也许下一次会
         有它发送我做一些事情的消息* /        //非阻塞试验请求完成
        MPI_TEST(安培; REQ,&安培;完成&安培;状态);
        如果(已完成)
        {
            //消息现在是在缓冲
            //处理消息
            // ...
            //再次激活请求
            MPI_Start(安培; REQ);
        }
    }    //取消并释放请求
    MPI_CANCEL(安培; REQ);
    MPI_REQUEST_FREE(安培; REQ);
}

持续经营有超过非持久那些轻微的性能优势,在previous code示例所示。重要的是,缓存而请求是活动的,调用 MPI_Start 后,即与前<$被访问C $ C> MPI_TEST 发出完成信号。持续发送/接收操作也符合非持久接收/发送操作,因此没有必要改变工人的code,他们仍可以使用 MPI_Isend

It's a master - slave situation. How can I make the master process search in a non-blocking way for a message transmitted to him. If at the point of searching there is no message transmited to master, it will continue with iterations. However, if there is a message transmitted to him, it will process the message and than continue with iterations. See the comment inside /* */

int main(int argc, char *argv[])
{
    int numprocs,
        rank;

    MPI_Request request;
    MPI_Status status;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
    if(rank == 0) // the searching process
    {
        for (int i=0; i < 4000000; i++)
        {   
            // do some stuff here; does not matter what

            /* see if any message has been transmitted to me at this point
             without blocking the process; if at this time it happens to be
             transmitted, do something and than continue with for iternations;
             or just continue with for iterations and maybe next time will
             have a message which sends me to do something */
        }
    }
    else
    {
        int flag = 1;
        while(flag) 
        {
            // something done that at some point changes flag
        }

        // send a message to process with rank 0 and don't get stuck here
        MPI_Isend(12, 1, MPI_INT, 0, 100, MPI_COMM_WORLD, &request);

        // some other stuff done

        // wait for message to be transmitted
        MPI_Wait(&request, &status);
    }

    MPI_Finalize();
    return 0;
}

解决方案

The non-blocking test for available messages is done using the MPI_Iprobe call. In your case it would look like:

int available;
MPI_Status status;

if(rank == 0) // the searching process
{
    for (int i=0; i < 4000000; i++)
    {   
        // do some stuff here; does not matter what

        /* see if any message has been transmitted to me at this point
         without blocking the process; if at this time it happens to be
         transmitted, do something and than continue with for iternations;
         or just continue with for iterations and maybe next time will
         have a message which sends me to do something */

        // Tag value 100 matches the value used in the send operation
        MPI_Iprobe(MPI_ANY_SOURCE, 100, MPI_COMM_WORLD, &available, &status);
        if (available)
        {
            // Message source rank is now available in status.MPI_SOURCE
            // Receive the message
            MPI_Recv(..., status.MPI_SOURCE, status.MPI_TAG, MPI_COMM_WORLD, &status);
        }
    }
}

MPI_ANY_SOURCE is used as wildcard rank, i.e. it instruct MPI_Irecv to check for messages from any source. If a corresponding send was posted, then available will be set to true, otherwise it will be set to false. The actual source of the message is also written to the MPI_SOURCE field of the status object. If the available flags indicates the availability of a matching message, one should then post a receive operation in order to receive it. It is important that the rank and the tag are explicitly specified in the receive operation, otherwise a different message could get received instead.

You could also use persistent connections. These behave very much like non-blocking operations with the important difference that they could be restarted multiple times. The same code with persistent connections would look like:

if(rank == 0) // the searching process
{
    MPI_Request req;
    MPI_Status status;
    int completed;

    // Prepare the persistent connection request
    MPI_Recv_init(buffer, buf_size, buf_type,
                  MPI_ANY_SOURCE, 100, MPI_COMM_WORLD, &req);
    // Make the request active
    MPI_Start(&req);

    for (int i=0; i < 4000000; i++)
    {   
        // do some stuff here; does not matter what

        /* see if any message has been transmitted to me at this point
         without blocking the process; if at this time it happens to be
         transmitted, do something and than continue with for iternations;
         or just continue with for iterations and maybe next time will
         have a message which sends me to do something */

        // Non-blocking Test for request completion
        MPI_Test(&req, &completed, &status);
        if (completed)
        {
            // Message is now in buffer
            // Process the message
            // ...
            // Activate the request again
            MPI_Start(&req);
        }
    }

    // Cancel and free the request
    MPI_Cancel(&req);
    MPI_Request_free(&req);
}

Persistent operations have a slight performance edge over the non-persistent ones, shown in the previous code sample. It is important that buffer is not accessed while the request is active, i.e. after the call to MPI_Start and before MPI_Test signals completion. Persistent send/receive operations also match non-persistent receive/send operations, therefore it is not necessary to change the code of the workers and they can still use MPI_Isend.

这篇关于搜索/等待在MS-MPI任何传输的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆