分布式内存应用瓶颈解决策略
立即解锁
发布时间: 2025-08-21 02:07:54 阅读量: 1 订阅数: 4 


高性能计算系统优化与应用设计
### 分布式内存应用瓶颈解决策略
#### 1. 同步策略
在大多数情况下,我们可以跳过同步操作。若担心遗漏或混淆信息,可使用 MPI 消息标签来设定所需顺序,或创建一个通信器,确保其中发送的所有消息都不会外传。
集体操作通常不需要同步进程(MPI_Barrier 除外),但部分操作可能会因使用的算法而进行同步。这在某些情况下是有益的,但我们应避免依赖此副作用,因为算法选择的改变可能导致同步点的意外缺失或增加。
仅在查找负载不平衡及其根源时,引入额外的同步点可能是有必要的。不过,这也可能掩盖负载不平衡的真实影响。
#### 2. 使用派生数据类型
派生数据类型是描述内存中数据布局的不透明 MPI 对象,可用于几乎所有的数据传输操作。早期,由于实现者难以保证其数据传输效率,应用程序员倾向于使用连续数据缓冲区,或手动进行数据打包和解包。
但如今,使用派生数据类型可能带来显著优势,尤其是在 MPI 实现提供原生支持的情况下。现代网络和内存控制器能够高效处理数据的分散、收集等操作,且 MPI 库内部的缓冲区管理和打包解包技术可能是应用程序员日常难以接触到的。不过,在自行编写特定的内存复制工具或数据类型展开循环之前,需确保这样做是值得的。
#### 3. 使用集体操作
应用程序员普遍担心集体操作性能不佳,老代码常重新实现所需的集体操作。但如今,除非有全新且卓越的算法,否则应尽量避免使用点对点替代方案。使用 MPI 集体操作可能带来显著性能提升,不过特殊情况需谨慎评估。
#### 4. 计算/通信重叠
通常不建议盲目追求计算/通信重叠,因为在确定其存在和实际效果之前,这样做很可能得不偿失。
当阻塞调用导致程序停滞,且排除其他可能原因(如程序已合理映射到平台、负载均衡良好、运行在调优后的 MPI 实现上)时,可考虑将阻塞通信转换为非阻塞通信。具体操作如下:
- 将阻塞发送操作(如 MPI_Send)替换为非阻塞版本(如 MPI_Isend),接收操作同理(MPI_Recv 替换为 MPI_Irecv),并在后续程序中使用 MPI_Wait 或 MPI_Test 进行收尾。
- 可使用 MPI_Waitall、MPI_Waitsome 和 MPI_Waitany 及其 MPI_Test 等效函数对多个操作进行分组,并按完成可能性对请求进行排序。
- 还可根据应用需求选择特殊的发送操作变体,如缓冲、同步或就绪发送,可选择是否使其非阻塞。
需要注意的是,标准 MPI_Send 根据消息大小、MPI 库内部缓冲区状态等因素,可能表现为不同的阻塞发送操作。小消息通常会尽快发送,类似于非阻塞发送;大消息可能使用会合协议,类似于同步发送。在没有明显计算/通信重叠的情况下,将这些操作替换为非阻塞版本可能不会带来性能提升。
此外,使用 MPI_Sendrecv 操作替换交叉的发送和接收对进行双边交换可能更有意义,因为它可能更好地利用底层硬件。但需注意,粗心地切换到非阻塞通信可能会引入额外的序列化问题。
为使数据能够移动,需要给 MPI 库提供帮助的机会。依赖异步进度不一定能解决问题,适时进行相关的 MPI 调用(如看似无用的 MPI_Iprobe)可能会显著加速程序,因为同步进度通常比异步进度开销更小。
最后,在进程间交换高度规则的情况下,阻塞传输可能有助于应用进程在运行时自我组织。
#### 5. 用 MPI - 3 非阻塞集体操作替换阻塞操作
Intel MPI Library 5.0 提供了 MPI - 3 功能,并与实现 MPI - 2.x 标准的 Intel MPI 4.x 产品线保持二进制兼容性。我们可以尝试使用 MPI - 3 标准中的非阻塞集体操作。
非阻塞集体操作相对成熟,但调优仍需改进。将阻塞集体操作(如 MPI_Barrier)替换为非阻塞版本并添加相应的收尾调用后,程序会变得更复杂,且难以像阻塞集体操作那样精确了解程序状态。此外,阻塞和非阻塞
0
0
复制全文
相关推荐










