MPI_Irecv是否随MPI_SSend自动完成?仍需MPI_Wait类调用吗?
问题解答
首先明确:MPI标准从未允许跳过MPI_Wait/MPI_Test来完成MPI_Irecv,不管发送方用的是哪种发送函数。你看到的现象是MPI发送函数的特性导致的“表面完成”,但本质上仍然需要调用完成函数。
为什么用MPI_Ssend时看起来不用Wait就“完成”?
MPI_Ssend是同步发送,它的返回条件是:接收方已经启动了匹配的接收操作(也就是你的MPI_Irecv已经调用),并且数据已经完全传输到接收方的缓冲区。这时候你确实能在接收缓冲区里看到数据,但这只是数据传输完成了——MPI_Irecv创建的请求对象还处于未完成状态,相关的MPI内部资源还没被释放。如果不调用MPI_Wait/MPI_Test,后续可能出现资源泄漏、请求状态混乱等未定义行为。
为什么换MPI_Send就必须Wait?
MPI_Send是标准发送,它的行为取决于MPI实现和系统缓冲:
- 如果系统有足够的缓冲空间,
MPI_Send会立即返回,数据暂时存在发送方的系统缓冲里,之后再异步传输到接收方。这时候接收方的MPI_Irecv虽然启动了,但数据还没到用户缓冲区,必须调用MPI_Wait来触发数据拷贝,完成接收操作。 - 只有当系统缓冲不足时,
MPI_Send才会阻塞,直到接收方匹配并开始接收数据,但即使这种情况,接收方仍然需要调用MPI_Wait来完成MPI_Irecv的请求处理。
关键结论
你观察到的差异是不同发送函数的语义导致的,但MPI标准严格要求所有非阻塞操作(包括MPI_Irecv)必须通过MPI_Wait/MPI_Test系列函数来完成。跳过这些调用属于违反标准的未定义行为,即使表面上数据已经可用,也不能省略。
内容的提问来源于stack exchange,提问作者boneheadgeek
相关产品推荐
相关产品推荐

