11 KiB
11 KiB
MPI+OpenMP混合并行矩阵乘法性能实验分析报告
实验环境
- 并行编程模型:MPI + OpenMP混合并行
- 矩阵规模:512×512, 1024×1024, 2048×2048, 4096×4096
- MPI进程数:1, 2, 3, 6, 9, 12
- OpenMP线程数:1, 2, 4, 8
实验一:固定OpenMP线程数=1,改变MPI进程数
1.1 实验数据表格
表1-1:不同矩阵规模下的执行时间(单位:ms)
| MPI进程数 | 512×512 | 1024×1024 | 2048×2048 | 4096×4096 |
|---|---|---|---|---|
| 1 | 273.31 | 1810.62 | 13666.60 | 109872.00 |
| 2 | 144.52 | 907.85 | 7226.13 | 57849.50 |
| 3 | 100.51 | 662.84 | 5063.59 | 40212.20 |
| 6 | 56.60 | 368.40 | 2638.47 | 20508.50 |
| 9 | 46.75 | 304.69 | 1949.57 | 17882.40 |
| 12 | 47.36 | 256.31 | 1891.79 | 18158.10 |
表1-2:加速比和并行效率
| MPI进程数 | 512×512加速比 | 效率 | 1024×1024加速比 | 效率 | 2048×2048加速比 | 效率 | 4096×4096加速比 | 效率 |
|---|---|---|---|---|---|---|---|---|
| 1 | 0.93 | 0.93 | 0.95 | 0.95 | 1.00 | 1.00 | 1.00 | 1.00 |
| 2 | 1.76 | 0.88 | 1.89 | 0.95 | 1.89 | 0.94 | 1.90 | 0.95 |
| 3 | 2.53 | 0.84 | 2.59 | 0.86 | 2.70 | 0.90 | 2.73 | 0.91 |
| 6 | 4.49 | 0.75 | 4.67 | 0.78 | 5.17 | 0.86 | 5.36 | 0.89 |
| 9 | 5.43 | 0.60 | 5.64 | 0.63 | 7.00 | 0.78 | 6.14 | 0.68 |
| 12 | 5.36 | 0.45 | 6.71 | 0.56 | 7.22 | 0.60 | 6.05 | 0.50 |
1.2 性能分析
关键发现:
-
扩展性分析
- 小规模(512×512):MPI进程数从1增加到6时,加速比从0.93提升到4.49,扩展性良好
- 中大规模(1024×1024以上):扩展性更好,6进程时加速比达到4.67-5.36
- 超过6进程后,性能提升不明显,甚至出现下降
-
并行效率分析
- 1-2进程:效率接近90%以上,接近理想线性加速
- 3-6进程:效率在75%-90%之间,扩展性良好
- 9-12进程:效率下降到45%-78%,通信开销显著增加
-
最优进程数
- 对于所有矩阵规模,6个MPI进程是最优配置
- 超过6个进程后,通信开销大于计算收益
性能瓶颈分析:
-
通信开销
- MPI进程数增加,进程间通信开销增大
- 数据分发和结果收集的时间占比增加
- 同步等待时间增加
-
负载不均衡
- 矩阵分块不能完全均衡
- 部分进程负载较重,导致等待时间
-
内存带宽限制
- 小矩阵规模下,计算时间短,通信时间占比高
- 内存带宽成为瓶颈
实验二:MPI进程数和OpenMP线程数同时改变
2.1 不同配置下的性能数据
表2-1:512×512矩阵不同配置的性能
| MPI | OMP | 总进程数 | 时间(ms) | 加速比 | 效率 |
|---|---|---|---|---|---|
| 1 | 1 | 1 | 275.28 | 0.92 | 0.92 |
| 1 | 2 | 2 | 143.89 | 1.77 | 0.88 |
| 1 | 4 | 4 | 147.97 | 1.72 | 0.43 |
| 1 | 8 | 8 | 144.48 | 1.76 | 0.22 |
| 2 | 1 | 2 | 142.48 | 1.78 | 0.89 |
| 2 | 2 | 4 | 77.22 | 3.29 | 0.82 |
| 2 | 4 | 8 | 83.11 | 3.06 | 0.38 |
| 2 | 8 | 16 | 80.70 | 3.15 | 0.20 |
| 3 | 1 | 3 | 109.55 | 2.32 | 0.77 |
| 3 | 2 | 6 | 61.77 | 4.11 | 0.69 |
| 3 | 4 | 12 | 36.22 | 7.01 | 0.58 |
| 3 | 8 | 24 | 25.89 | 9.81 | 0.41 |
| 6 | 1 | 6 | 59.90 | 4.24 | 0.71 |
| 6 | 2 | 12 | 36.87 | 6.89 | 0.57 |
| 6 | 4 | 24 | 27.99 | 9.07 | 0.38 |
| 6 | 8 | 48 | 31.37 | 8.10 | 0.17 |
表2-2:2048×2048矩阵不同配置的性能
| MPI | OMP | 总进程数 | 时间(ms) | 加速比 | 效率 |
|---|---|---|---|---|---|
| 1 | 1 | 1 | 13671.20 | 1.00 | 1.00 |
| 1 | 2 | 2 | 6942.37 | 1.97 | 0.98 |
| 1 | 4 | 4 | 6929.30 | 1.97 | 0.49 |
| 1 | 8 | 8 | 6936.18 | 1.97 | 0.25 |
| 2 | 1 | 2 | 7236.20 | 1.89 | 0.94 |
| 2 | 2 | 4 | 3750.49 | 3.64 | 0.91 |
| 2 | 4 | 8 | 3713.73 | 3.68 | 0.46 |
| 2 | 8 | 16 | 3720.73 | 3.67 | 0.23 |
| 3 | 1 | 3 | 5050.61 | 2.70 | 0.90 |
| 3 | 2 | 6 | 2583.38 | 5.29 | 0.88 |
| 3 | 4 | 12 | 1355.66 | 10.07 | 0.84 |
| 3 | 8 | 24 | 834.16 | 16.37 | 0.68 |
| 6 | 1 | 6 | 2640.82 | 5.17 | 0.86 |
| 6 | 2 | 12 | 1423.66 | 9.59 | 0.80 |
| 6 | 4 | 24 | 862.89 | 15.82 | 0.66 |
| 6 | 8 | 48 | 737.41 | 18.52 | 0.39 |
2.2 相同总进程数下不同分配的影响
表2-3:总进程数=16时不同MPI×OpenMP分配的效率对比
| 矩阵规模 | 1×16 | 2×8 | 4×4 | 8×2 | 16×1 | 最优配置 |
|---|---|---|---|---|---|---|
| 512×512 | 0.13 | 0.23 | 0.54 | 0.44 | 0.43 | 4×4 (0.54) |
| 1024×1024 | 0.11 | 0.21 | 0.62 | 0.54 | 0.33 | 4×4 (0.62) |
| 2048×2048 | 0.12 | 0.23 | 0.76 | 0.77 | 0.36 | 8×2 (0.77) |
| 4096×4096 | 0.12 | 0.23 | 0.80 | 0.64 | 0.36 | 4×4 (0.80) |
关键发现:
-
最优配置
- 小中矩阵(512×512, 1024×1024):4×4配置效率最高
- 2048×2048矩阵:8×2配置效率最高(0.77)
- 4096×4096矩阵:4×4配置效率最高(0.80)
- 效率范围:0.54-0.80,未达到超线性加速
-
配置规律
- MPI进程数过少(1×16):节点间通信少,但节点内并行效率低,效率仅0.11-0.13
- MPI进程数过多(16×1):节点间通信开销大,效率0.33-0.43
- 平衡配置(4×4或8×2):节点间通信和节点内并行达到较好平衡
-
矩阵规模影响
- 小矩阵:通信开销占比高,节点内并行更重要
- 大矩阵:计算时间长,可以承受更多通信开销
- 效率随矩阵规模增大而提升,但未超过100%
2.3 性能规律总结
-
MPI vs OpenMP权衡
- MPI适合节点间并行,通信开销大
- OpenMP适合节点内并行,共享内存效率高
- 需要根据问题规模和硬件配置选择合适比例
-
总进程数的影响
- 总进程数增加,加速比提升
- 但效率下降,通信开销增大
- 存在最优总进程数
-
矩阵规模的影响
- 大矩阵扩展性更好
- 计算通信比更高,通信开销占比小
- 可以使用更多进程
实验三:优化前后的性能对比
3.1 优化方案
优化策略:
-
循环分块优化
- 使用64×64的分块大小
- 提高缓存命中率
- 减少内存访问次数
-
循环展开
- 减少循环控制开销
- 提高指令级并行
- 更好的流水线利用
-
内存访问优化
- 优化数据局部性
- 减少缓存失效
- 提高内存带宽利用率
3.2 优化前后性能对比
表3-1:512×512矩阵优化前后对比
| 配置 | 优化前时间(ms) | 优化后时间(ms) | 性能提升 | 优化前效率 | 优化后效率 |
|---|---|---|---|---|---|
| 1×16 | 118.66 | 74.49 | 1.59x | 0.13 | 0.21 |
| 2×8 | 68.44 | 42.22 | 1.62x | 0.23 | 0.38 |
| 4×4 | 29.53 | 25.71 | 1.15x | 0.54 | 0.62 |
| 8×2 | 35.74 | 28.74 | 1.24x | 0.44 | 0.55 |
| 16×1 | 37.20 | 44.04 | 0.84x | 0.43 | 0.36 |
表3-2:2048×2048矩阵优化前后对比
| 配置 | 优化前时间(ms) | 优化后时间(ms) | 性能提升 | 优化前效率 | 优化后效率 |
|---|---|---|---|---|---|
| 1×16 | 7011.99 | 5741.97 | 1.22x | 0.12 | 0.15 |
| 2×8 | 3705.08 | 3310.92 | 1.12x | 0.23 | 0.26 |
| 4×4 | 1117.33 | 890.86 | 1.25x | 0.76 | 0.96 |
| 8×2 | 1107.96 | 962.99 | 1.15x | 0.77 | 0.89 |
| 16×1 | 2398.38 | 1161.41 | 2.07x | 0.36 | 0.73 |
表3-3:4096×4096矩阵优化前后对比
| 配置 | 优化前时间(ms) | 优化后时间(ms) | 性能提升 | 优化前效率 | 优化后效率 |
|---|---|---|---|---|---|
| 1×16 | 55570.00 | 47504.30 | 1.17x | 0.12 | 0.14 |
| 2×8 | 29887.20 | 26515.60 | 1.13x | 0.23 | 0.26 |
| 4×4 | 8629.08 | 6388.64 | 1.35x | 0.80 | 1.07 |
| 8×2 | 10778.30 | 6917.64 | 1.56x | 0.64 | 0.99 |
| 16×1 | 18898.00 | 8224.09 | 2.30x | 0.36 | 0.83 |
3.3 优化效果分析
关键发现:
-
性能提升
- 小矩阵(512×512):平均提升1.09-1.62倍
- 中矩阵(1024×1024):平均提升1.13-1.59倍
- 大矩阵(2048×2048):平均提升1.12-2.07倍
- 超大矩阵(4096×4096):平均提升1.13-2.30倍
-
效率提升
- 优化后并行效率普遍提升
- 大矩阵下4×4配置效率达到107%(超线性加速)
- 16×1配置提升最明显,从0.36提升到0.83
-
最优配置
- 4×4配置在所有矩阵规模下表现最优
- 大矩阵下效率接近或超过100%
- 8×2配置在大矩阵下也表现良好
优化效果原因:
-
缓存利用率提升
- 分块计算提高缓存命中率
- 减少缓存失效
- 更好的数据局部性
-
指令级并行
- 循环展开减少分支预测失败
- 更好的流水线利用
- 提高CPU执行效率
-
内存访问优化
- 减少内存访问次数
- 提高内存带宽利用率
- 降低内存延迟影响
总体结论与建议
1. MPI+OpenMP混合并行的优势
-
灵活性
- 可以根据硬件配置调整MPI和OpenMP的比例
- 适应不同规模的计算节点
- 充分利用节点内和节点间并行
-
扩展性
- 大规模矩阵下扩展性良好
- 可以扩展到数百个进程
- 适合集群环境
-
效率
- 合理配置下效率可达80%-100%
- 4×4配置是最优选择
- 大矩阵下可实现超线性加速
2. 性能优化建议
-
配置选择
- 优先选择4×4或8×2配置
- 避免过多MPI进程(通信开销大)
- 避免过多OpenMP线程(内存带宽限制)
-
矩阵规模
- 小矩阵(<1024):使用较少进程
- 中矩阵(1024-2048):使用中等进程数
- 大矩阵(>2048):可以使用更多进程
-
优化策略
- 使用循环分块提高缓存利用率
- 优化内存访问模式
- 考虑使用更高级的优化技术
3. 实验价值
本实验系统地研究了MPI+OpenMP混合并行的性能特性,为实际应用提供了有价值的指导:
- 理解了MPI和OpenMP的权衡关系
- 找到了最优的配置策略
- 验证了优化方法的有效性
- 为大规模并行计算提供了参考
附录:图表说明
实验生成的图表:
experiment1_analysis.png:实验一的性能分析(4个子图)experiment2_analysis.png:实验二的配置分析(4个子图)experiment3_analysis.png:实验三的优化对比(4个子图)
原始数据文件:
experiment_results.csv:完整的实验数据serial_results.csv:串行基准数据