在MPI_Iprobe中,需要多次检查标志以确定是否有任何消息,一种方法是将其置于while循环中,我想知道这种方法是否等同于MPI_Probe 因为它基本上以不同的方式阻止了探测, 这是使用Iprobe的错误方法吗?
int flag=0
while(flag==0)
{
MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag,&status);
cout<<myrank<<" "<<flag<<endl;
}
if(flag)
{
MPI_Get_count(&status, MPI_INT, &count);
MPI_Irecv(&rcvbuff,count, MPI_INT,destination.at(0),0, MPI_COMM_WORLD, &request);
}
答案 0 :(得分:5)
是的,基本上你所建议的MPI_Iprobe
周围的循环与MPI_Probe
具有相同的语义。但是,您通常应该更喜欢复合操作,而不是自己实现。因此,请使用MPI_Probe
代替MPI_Iprobe
- 循环。使用MPI_Wait
代替MPI_Test
- 循环。尽可能使用集合而不是单独的点对点消息。
如果您希望与计算重叠通信,则同步MPI_I...
函数通常很有用,但您不应该使用它们来重新实现现有的MPI功能。
通过使用MPI_Probe
,您可以为实现提供优化和调优的自由。一方面,MPI可以阻塞,直到出现消息,从而节省CPU周期/功率。另一方面,它可以具有较低的延迟,因为没有浪费时间一次又一次地进入MPI堆栈。使用PMPI层的任何工具使用一个MPI_Probe
调用而不是数千个MPI_Iprobe
调用也更好。我已经实现了&gt;只需将MPI_Test
循环替换为MPI_Waitany
,即可在现实世界的HPC应用程序中实现10%的加速。
唯一的例外是,如果你已经用尽了MPI实现的调整选项,并且可以肯定地表明你自己的轮重新实现比MPI提供的复合操作更好。
MPI_Irecv
电话也很奇怪。尽管知道已经有待处理的消息,您是否有充分的理由使用异步接收?为什么不发布MPI_Irecv
而不是首先进行探测?如果您知道分配接收缓冲区所需的最大大小,您还可以在MPI_Irecv
上发布MPI_ANY_SOURCE
,其接收计数大于发送计数。