如何测量MPI Isend/Irecv及非阻塞点对点通信的耗时?
测量MPI Isend/Irecv耗时的方法
直接计时搭配MPI_Wait/MPI_Waitall
非阻塞通信调用(MPI_Isend/MPI_Irecv)会立即返回,必须等待请求完成后,才能得到实际的通信耗时。使用MPI标准的墙钟计时函数MPI_Wtime()即可实现:
- 发起通信前记录起始时间戳
- 调用非阻塞通信接口
- 用
MPI_Wait等待对应请求完成 - 记录结束时间戳,两者差值即为通信耗时
示例代码:
double start, end; MPI_Request req; int data; int dest_rank = 1, source_rank = 0, tag = 0; // 测量Isend耗时 start = MPI_Wtime(); MPI_Isend(&data, 1, MPI_INT, dest_rank, tag, MPI_COMM_WORLD, &req); MPI_Wait(&req, MPI_STATUS_IGNORE); end = MPI_Wtime(); printf("Isend耗时: %lf秒\n", end - start); // 测量Irecv耗时 start = MPI_Wtime(); MPI_Irecv(&data, 1, MPI_INT, source_rank, tag, MPI_COMM_WORLD, &req); MPI_Wait(&req, MPI_STATUS_IGNORE); end = MPI_Wtime(); printf("Irecv耗时: %lf秒\n", end - start);
跟踪请求完成时间(适合计算通信重叠场景)
如果需要在通信同时执行其他计算,不想阻塞在MPI_Wait上,可以用MPI_Test轮询请求状态,待请求完成后计算耗时:
- 发起非阻塞通信时记录起始时间
- 插入并行计算逻辑
- 轮询检查请求是否完成,完成后记录结束时间并计算差值
示例代码:
double start, end; MPI_Request req; int data, flag = 0; int dest_rank = 1, tag = 0; start = MPI_Wtime(); MPI_Isend(&data, 1, MPI_INT, dest_rank, tag, MPI_COMM_WORLD, &req); // 执行并行计算任务 // ... // 轮询等待请求完成 while (!flag) { MPI_Test(&req, &flag, MPI_STATUS_IGNORE); } end = MPI_Wtime(); printf("Isend实际通信耗时: %lf秒\n", end - start);
关键注意事项
- 必须等待请求完成(
MPI_Wait/MPI_Test/MPI_Waitall等接口)再计算耗时,否则得到的只是发起通信的时间,不是实际传输时间 - 建议多次测量取平均值,抵消系统调度、网络波动带来的单次误差
- 优先使用
MPI_Wtime()而非系统clock()函数,前者是跨平台的墙钟时间,更适合测量通信耗时 - 测量双向通信延迟时,需确保发送方和接收方的时间戳对应,避免时钟同步问题
内容的提问来源于stack exchange,提问作者Vishal Deka
相关产品推荐
相关产品推荐

