评估通信对MPI程序运行时的占比:分析缺陷与遗漏问题
背景
假设有一个包含多个消息传递事件与计算任务的复杂MPI程序,其通信模式为双向环形消息传递(如图所示)。通信基于异步MPI函数MPI_Irecv、MPI_Isend及MPI_Wait/MPI_Waitall/MPI_Waitsome实现,封装于高层通信函数中并附带少量簿记操作。程序先提前发布收发请求,再执行密集计算,最后调用等待函数,以实现通信与计算重叠。
性能分析
实现完成后,需分析其性能以回答“程序在通信上耗时占比多少?”的问题。采用MPI采样分析器(详见include/mpi_spot_profiler.h)在典型配置下对程序进行分析,各进程的分析结果独立存储。
虚构的分析时间线图中,Y轴(向下)代表时间,X轴(向右)代表MPI进程。原分析将通信耗时占比等同于图中蓝、黄、绿框覆盖的2D区域占比,计算公式为:
p = (a0 + a1 + a2) + (b0 + b1 + b2) + (c0 + c1 + c2) ------------------------------------------------ , T*3
其中3为MPI进程数,简化后为:
p = average(a) + average(b) + average(c) ------------------------------------ . T
据此得出结论:99%的运行时间用于密集计算,剩余1%用于高层通信函数。
技术问询解答
1. 上述分析存在哪些缺陷?
- 混淆了单进程通信时间占比与全局有效耗时占比:原公式计算的是所有进程通信时间的平均值占单进程总时间的比例,但并行程序中通信与计算重叠的部分并没有占用额外的全局有效时间。比如若通信完全和计算重叠,单进程看有通信耗时,但全局层面通信没耽误整体运行,此时真实的通信耗时占比应为0,而非公式算出的1%。
- 误将异步通信的调用时间等同于实际通信耗时:
MPI_Irecv/MPI_Isend是异步调用,高层通信函数的耗时大多是簿记操作,真正的消息传输是在后台与计算并行完成的,这部分重叠的时间不应该被计入“通信耗时”——因为它没有抢占计算的时间资源。 - 忽略了进程间的时间差异:公式假设所有进程的总运行时间T完全一致,但实际并行程序中进程的总耗时可能因负载、通信延迟等存在差异,统一用T计算会导致结果失真。
2. 若双向环形消息传递存在固有同步开销,该开销是否会被上述公式(如等待函数的区域)捕获?
分两种情况:
- 如果同步开销表现为进程在
MPI_Wait系列函数中主动阻塞等待(比如等待其他进程的消息完成),这部分阻塞时间会被统计到等待函数的耗时(即公式中的a/b/c),能被计算覆盖; - 如果同步开销是隐式的计算空转(比如环形依赖导致某进程的计算因未收到前置消息而暂停,这部分时间被统计为计算耗时),原公式无法捕获——因为它只统计高层通信函数的时间,不会把计算阶段的空转归为通信开销。
3. 是否存在任何与通信相关的开销未被上述分析覆盖?
存在多种未被覆盖的通信相关开销:
- 隐式同步空转时间:因环形通信的依赖关系,进程在计算阶段等待消息到达而产生的空转时间,被统计为计算耗时,但根源是通信;
- MPI后台通信的CPU开销:异步通信在后台执行时占用的CPU资源(如网络处理线程的开销),不会被计入高层通信函数的时间;
- 数据拷贝开销:消息在用户缓冲区与MPI内部缓冲区之间的拷贝操作,若在计算阶段后台完成,不会被统计到高层通信函数耗时中;
- 负载不均衡导致的等待时间:部分进程因通信延迟提前完成计算,被迫等待其他进程,这部分等待时间被算为计算耗时,但本质是通信引发的;
- MPI库内部隐性开销:比如请求队列管理、底层协议处理等操作,若在非高层通信函数的时机执行,也不会被分析统计。
内容的提问来源于stack exchange,提问作者Nitin Malapally
相关产品推荐
相关产品推荐

