基于C语言的MPI非阻塞收发与Waitall实现伙伴任务通信需求及问题
基于C语言的MPI非阻塞伙伴通信程序实现
我来帮你补全并完善这个MPI非阻塞通信的程序,先明确你的核心需求:
- 用C语言编写MPI程序
- 使用**非阻塞发送(MPI_Isend)和非阻塞接收(MPI_Irecv)**完成进程间通信
- 伙伴进程规则:对于rank为
taskid的进程,伙伴是taskid + numtasks/2;后半段进程的伙伴则是taskid - numtasks/2(避免超出进程总数) - 发送的消息内容为发送方自身的rank值
接下来是完整的可运行代码,我会在关键部分加上注释说明:
#include "mpi.h" #include <stdio.h> #include <stdlib.h> #define MASTER 0 int main (int argc, char *argv[]) { int numtasks, taskid, partner, message; char hostname[MPI_MAX_PROCESSOR_NAME]; int len; // 补充你之前省略的变量 MPI_Request send_req, recv_req; // 非阻塞操作的请求句柄,用于跟踪操作状态 MPI_Status send_status, recv_status; // 存储非阻塞操作完成后的状态信息 MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &numtasks); // 获取总进程数 MPI_Comm_rank(MPI_COMM_WORLD, &taskid); // 获取当前进程rank MPI_Get_processor_name(hostname, &len); // 获取运行进程的主机名 // 关键检查:总进程数必须是偶数,否则伙伴规则无法覆盖所有进程 if (numtasks % 2 != 0) { if (taskid == MASTER) { printf("Error: 进程总数必须为偶数!当前进程数:%d\n", numtasks); } MPI_Finalize(); exit(EXIT_FAILURE); } // 计算伙伴进程的rank partner = taskid + numtasks / 2; // 处理后半段进程的伙伴(例如总进程数为4时,rank2的伙伴应该是0,而不是4) if (partner >= numtasks) { partner -= numtasks; } printf("进程 %d (运行在主机 %s) 的伙伴是进程 %d\n", taskid, hostname, partner); // 非阻塞发送:将自身rank发送给伙伴进程 MPI_Isend(&taskid, 1, MPI_INT, partner, 0, MPI_COMM_WORLD, &send_req); // 非阻塞接收:从伙伴进程接收消息到message变量 MPI_Irecv(&message, 1, MPI_INT, partner, 0, MPI_COMM_WORLD, &recv_req); // 等待非阻塞发送和接收操作完成,确保数据安全传输 MPI_Wait(&send_req, &send_status); MPI_Wait(&recv_req, &recv_status); // 打印接收结果 printf("进程 %d 从伙伴进程 %d 接收到消息:%d\n", taskid, partner, message); MPI_Finalize(); return EXIT_SUCCESS; }
关键代码解释
- MPI_Request与MPI_Status:非阻塞MPI调用不会等待操作完成,所以需要用
MPI_Request来跟踪每个非阻塞操作的状态;MPI_Status则用于获取操作完成后的详细信息(比如实际接收的数据量)。 - 伙伴计算逻辑:前半段进程的伙伴是自身rank加上总进程数的一半,后半段进程的伙伴则需要减去总进程数,避免rank超出有效范围。
- 非阻塞调用与等待:
MPI_Isend和MPI_Irecv会立即返回,之后必须用MPI_Wait等待操作完成,否则可能出现数据未传输完成就继续执行后续代码的问题。 - 错误处理:加入了总进程数是否为偶数的检查,确保所有进程都能找到对应的伙伴,避免程序异常。
编译与运行
- 编译命令:
mpicc -o non_blocking_partner non_blocking_partner.c - 运行命令(以4个进程为例):
mpirun -np 4 ./non_blocking_partner
运行后你会看到每个进程都能正确找到伙伴,并成功发送和接收消息。
内容的提问来源于stack exchange,提问作者SteamedCow
相关产品推荐
相关产品推荐

