搜索/等待在MS-MPI任何传输 [英] Search/wait for any transmission in 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屋!