按MPI_Rsend man papers,为了使用MPI_Rsend,我们需要保证已发布接收。如果在调用ready发送之前没有发送接收是错误的。但是如何保证已经发布了一个接收???。我试图找到一些关于MPI_Rsend的例子,但我找不到任何东西。如何得到这个错误?
在这个链接MPI_RSend_error中,最后有人说:" 简单地不使用MPI_Rsend - 它是一种古老的,它的行为没有明确定义,它被所有的所有人淘汰了现代MPI库中的协议优化"。那么,哪些MPI库正好实现了RSend?事实上,在某些算法中,使用MPI_Rsend会比MPI_Send提供更好的性能
示例代码:
void AllGather_ring_RSend(void* data, int count, MPI_Datatype datatype,MPI_Comm communicator)
{
int me;
MPI_Comm_rank(communicator, &me);
int world_size;
MPI_Comm_size(communicator, &world_size);
int next=me+1;
if(next>=world_size)
next=0;
int prev=me-1;
if(prev<0)
prev=world_size-1;
int i,curi=me;
for(i=0;i<world_size-1;i++)
{
MPI_Rsend(data+curi*sizeof(int), count, datatype, next, 0, communicator);
curi=curi-1;
if(curi<0)
curi=world_size-1;
MPI_Recv(data+curi*sizeof(int), count, datatype, prev, 0, communicator, MPI_STATUS_IGNORE);
}
}
void main(int argc, char** argv) {
char processor_name[MPI_MAX_PROCESSOR_NAME];
MPI_Init(&argc,&argv);
int world_rank,world_size,namelen;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
int* buff=(int*) malloc(world_size*sizeof(int));
int i;
for (i = 0; i < world_size; i++) {
buff[i]=world_rank;
}
if(world_rank==0)
for (i = 0; i < world_size; i++)
printf("%d\n",buff[i]);
MPI_Barrier(MPI_COMM_WORLD);
AllGather_ring_RSend(buff,1,MPI_INT,MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();
}
&#13;
在此代码中,已发布的接收进程???
答案 0 :(得分:3)
MPI没有提供内置机制来检查远程排名是否已经发布了接收操作。由程序的逻辑来确保例如通过例如让接收方以某种方式通知发送方(例如通过消息或完成同步调用,如MPI_(I)Barrier
)它已发布接收,因此启动就绪是安全的 - 模式发送。
正如我已经说过的那样,现成模式发送已经被现代网络和MPI实现的工作方式所淘汰。小消息已经异步发送(使用急切的发送协议),而较大消息的延迟节省(如果有的话)则非常平台 - 和网络 - &amp;实现有关。 未正确使用的就绪模式发送的结果未在MPI标准中定义,并且允许实现将标准模式替换为现成模式。因此很容易陷入本地模式实现了就绪发送的行为,并以不正确的MPI代码结束。此外,您甚至无法编写可靠地在所有MPI实现上产生错误的代码。
将标准模式实现就绪模式的MPI库的示例是Open MPI。 MPICH通过在消息接收时检查匹配的接收并且如果没有找到则返回错误来实现针对急切消息的就绪模式,这不会提供比已经发布的接收的标准发送的任何性能益处(如果我&#,MPICH人可以纠正我) 39;我错了。)