Parallel processing 存在MPI_ANY_源和MPI_ANY_标记时MPI消息的非超车属性
假设我有一台服务器,它处理由不同类型的MPI标记标识的多种请求Parallel processing 存在MPI_ANY_源和MPI_ANY_标记时MPI消息的非超车属性,parallel-processing,mpi,Parallel Processing,Mpi,假设我有一台服务器,它处理由不同类型的MPI标记标识的多种请求 while(!stop) { MPI_Iprobe(MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&ready,&status); if(ready) { src = status.MPI_SOURCE; switch(status.MPI_TAG) { case MPI_REQ_A:
while(!stop)
{
MPI_Iprobe(MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&ready,&status);
if(ready)
{
src = status.MPI_SOURCE;
switch(status.MPI_TAG)
{
case MPI_REQ_A:
MPI_Irecv(...);
//do something else useful while waiting
MPI_Wait(...);
break;
case MPI_REQ_B:
MPI_Irecv(...);
//do something else useful while waiting
MPI_Wait(...);
break;
}
}
//do something else before calling MPI_Iprobe() again
}
有N个客户端向服务器发送请求。
如果每个客户端发送消息,如下代码所示:
for( int i=0; i<k ; i++ )
{
MPI_Send(....,MPI_REQ_A,..);
MPI_Send(....,MPI_REQ_B,..);
}
for(int i=0;i根据:
如果发件人连续向同一目的地发送两条消息,
并且两者匹配相同的接收,则此操作无法接收
如果第一条消息仍然挂起,则显示第二条消息
现在,如果在客户机中展开该循环,它基本上会执行以下操作:
MPI_Send(....,MPI_REQ_A,..); // i
MPI_Send(....,MPI_REQ_B,..); // i
MPI_Send(....,MPI_REQ_A,..); // i + 1
MPI_Send(....,MPI_REQ_B,..); // i + 1
MPI_Send(....,MPI_REQ_A,..); // i + 2
MPI_Send(....,MPI_REQ_B,..); // i + 2
...
由于服务器的接收与所有这些呼叫都匹配,因此保证该客户端的消息以准确的顺序接收。因此,您的两个问题的答案都是是:在任何一个客户端上,消息都是按其发布的顺序发送的
另一方面,对于从不同客户端接收消息的顺序没有要求。例如,以下场景完全合法:
服务器发布其第一次接收
所有客户端都会发布其第一次发送和阻止
服务器将其接收与客户端X的第一条消息相匹配,并发布第二条接收消息
客户端X的第一次发送完成,并发布第二次发送
同时,服务器将其第二次接收与客户端Y的第一次发送相匹配,并发布其第三次接收
客户端Y的第一次发送完成,并发布第二次发送
此时,服务器可以自由地将其第三次接收匹配到客户端X的第二次发送,而不是任何其他客户端的第一次发送
依此类推,服务器可以在只接受来自客户端X和Y的发送之间进行切换,而其他的发送将处于饥饿状态。如果在客户端的for循环中,我使用MPI_Isend(NULL,0,MPI_INT,…)发送空消息,而没有任何匹配的MPI_Wait(),那么我的两个问题的答案是否仍然是“是”和“是”?是:对于非阻塞操作,“顺序”定义为发起操作的MPI调用的顺序。但是,饥饿可能是一个更大的问题,因为现在服务器可以在任何其他客户端之前合法地将其所有接收匹配到同一个客户端的发送,这可能导致完全串行执行N