---
title: 示例5：MPI通信阻塞函数耗时占比分析
description: "MPI应用进行数据通信时，默认使用MPI_Send与MPI_Recv函数进行发送、接收数据，但该API存在阻塞式通信，容易影响其他代码执行，造成整个应用执行时间被拉长，效率降低。"
url: https://www.hikunpeng.com/document/detail/zh/kunpengdevps/profiler/demo/KnowHow_0008.html
sourcePath: /source/zh/kunpengdevps/profiler/demo/KnowHow_0008.html
indexId: b4e463f7e6288e5fff10a333585bca4461dfdc9f1bc6fabb6e6b72cd73f370e155
---
# 示例5：MPI通信阻塞函数耗时占比分析

#### 现象

MPI应用进行数据通信时，默认使用MPI_Send与MPI_Recv函数进行发送、接收数据，但该API存在阻塞式通信，容易影响其他代码执行，造成整个应用执行时间被拉长，效率降低。


#### 调优思路

通过鲲鹏DevKit系统性能分析的HPC应用分析，了解API在整个应用中所消耗的时间与阻塞时间占比，调整使用异步API MPI_Isend与MPI_Irecv，减少阻塞时间，使应用执行效率提高。


#### 操作步骤

1. 请从GitHub(https://github.com/kunpengcompute/devkitdemo/tree/main/Hyper_tuner/testdemo/Know-how)下载代码样例send_recv.cpp，并进行编译。
  1 mpicc send_recv.cpp -O3 -o send_recv -fopenmp -lm

2. 新建HPC应用分析任务，分析当前应用。
  单击系统性能分析后面的，选择“通用分析”，打开新建任务页面，选择“HPC应用分析”，参数配置完成后单击“确认”启动HPC应用分析任务。

  图1 新建HPC应用分析任务

**表1 配置参数说明**

| 参数 | 说明 |
| --- | --- |
| 分析类型 | HPC应用分析。 |
| 分析对象 | 应用。 |
| 模式 | Launch Application。 |
| 应用路径 | 输入程序所在的绝对路径，例如本示例将代码样例放在服务器“/opt/testdemo/send\_recv”路径下（多节点环境下应用在对应目录下存在）。 |
| 分析模式 | 统计分析。 |
| 共享目录 | 单节点情况下填入存在且可用的目录，多节点情况下需填入节点间的共享目录；例如本示例是在两个节点下进行采集所以填入节点间的共享目录“/home/share”。 |
| mpirun所在路径 | mpirun命令所在绝对路径。 |
| mpirun参数 | \-\-allow\-run\-as\-root \-H 节点IP:rank数（例如：\-\-allow\-run\-as\-root \-H 192.168.1.10:4）。 |
| 采样模式 | Summary模式。 |
| 其他参数 | 默认。 |


3. 查看任务结果。
  观察到MPI Wait Rate占比较高，且全为Communication-Point to point，进一步分析MPI运行时指标，发现MPI_Send阻塞时间占比较高，影响应用执行效率。

  图2 分析结果

  图3 MPI运行时指标

4. 分析源码。
  代码内使用MPI_Send与MPI_Recv发送、接收数据，容易造成阻塞，影响其他代码执行。 1 2 ierr = MPI_Send(&number, send_len, MPI_INT, from_rank, tag, MPI_COMM_WORLD); ierr = MPI_Recv(&number, recv_len, MPI_INT, from_rank, tag, MPI_COMM_WORLD, &status);

5. 添加MPI_Request变量声明。
  在源码开头添加MPI_Request变量声明，因调用MPI_Isend和MPI_Irecv需要使用该变量；此声明在示例源码中已添加，不调用时无影响。

  1 MPI_Request request;

6. 修改为异步接口。
  将MPI_Send与MPI_Recv修改为异步API MPI_Isend与MPI_Irecv，减少发送、接收数据时的阻塞时间。 1 2 ierr = MPI_Isend(&number, send_len, MPI_INT, from_rank, tag, MPI_COMM_WORLD, &request); ierr = MPI_Irecv(&number, recv_len, MPI_INT, from_rank, tag, MPI_COMM_WORLD, &request);

7. 适配异步通信，增加异步等待。
  使用MPI_Isend和MPI_Irecv等非阻塞通信函数时，必须使用等待机制来确保通信完成，在源码最后调用前增加异步等待。

  1 MPI_Wait(&request, &status);

8. 重新编译，再次分析。
  使用1中的命令重新编译应用并使用工具进行分析，观察应用执行时间和MPI运行时指标。


#### 优化效果

优化后，应用执行时间从60.01s缩短至30s。


图4 优化后数据

图5 优化后的MPI运行时指标
