hpc-lab-code/work/README.md
2026-01-21 18:02:30 +08:00

304 lines
7.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# MPI-OpenMP混合并行矩阵乘法实验
## 项目结构
```
gemm/
├── gemm_serial.cpp # 串行版本实现
├── gemm_parallel.cpp # MPI-OpenMP混合并行版本
├── xmake.lua # 构建配置文件
├── run_experiments.sh # 自动化测试脚本
└── README.md # 本文件
```
## 编译说明
### 使用xmake编译推荐
```bash
cd /home/yly/dev/hpc-lab-code/work/gemm
xmake build
```
编译后的可执行文件位于:
- `build/linux/x86_64/release/gemm_serial`
- `build/linux/x86_64/release/gemm_parallel`
### 手动编译
```bash
# 串行版本
mpic++ -O3 -march=native gemm_serial.cpp -o gemm_serial
# 并行版本
mpic++ -O3 -march=native -fopenmp gemm_parallel.cpp -o gemm_parallel -lm
```
## 运行说明
### 串行版本
```bash
./build/linux/x86_64/release/gemm_serial M N K use-blas
```
参数说明:
- M: 左矩阵行数
- N: 左矩阵列数/右矩阵行数
- K: 右矩阵列数
- use-blas: 是否使用BLAS0=不使用1=使用,当前版本未实现)
示例:
```bash
./build/linux/x86_64/release/gemm_serial 1024 1024 1024 0
```
### 并行版本
```bash
mpirun -np <进程数> ./build/linux/x86_64/release/gemm_parallel M N K
```
参数说明:
- 进程数: MPI进程数量
- M, N, K: 矩阵维度
示例:
```bash
# 使用4个MPI进程矩阵大小2048x2048x2048
mpirun -np 4 ./build/linux/x86_64/release/gemm_parallel 2048 2048 2048
# 使用16个MPI进程8个OpenMP线程
export OMP_NUM_THREADS=8
mpirun -np 16 ./build/linux/x86_64/release/gemm_parallel 4096 4096 4096
```
## 自动化测试
使用提供的脚本自动运行所有实验并收集数据:
```bash
cd /home/yly/dev/hpc-lab-code/work/gemm
./run_experiments.sh
```
脚本会自动:
1. 编译程序
2. 运行串行基准测试
3. 运行实验一固定OpenMP线程数改变MPI进程数
4. 运行实验二同时改变MPI进程数和OpenMP线程数
5. 运行实验三固定总处理器数改变MPI/OpenMP组合
6. 保存所有结果到CSV文件
## 实验设计
### 实验一MPI进程数扩展性
**目的**研究在OpenMP线程数固定为1时不同MPI进程数的性能表现
**变量**
- 固定OpenMP线程数 = 1
- 改变MPI进程数 = 1, 2, 4, 9, 16
- 测试:不同矩阵尺寸 512, 1024, 2048, 4096
**测量指标**
- 运行时间ms
- 加速比 = T_serial / T_parallel
- 效率 = 加速比 / MPI进程数
### 实验二MPI-OpenMP混合并行扩展性
**目的**研究同时改变MPI进程数和OpenMP线程数时的性能表现
**变量**
- OpenMP线程数1, 2, 4, 8
- MPI进程数1, 2, 4, 9, 16
- 总处理器数 = MPI进程数 × OpenMP线程数
- 测试:不同矩阵尺寸 512, 1024, 2048, 4096
**测量指标**
- 运行时间ms
- 加速比 = T_serial / T_parallel
- 效率 = 加速比 / 总处理器数
### 实验三MPI/OpenMP组合优化
**目的**在总处理器数固定的情况下研究不同MPI/OpenMP组合对性能的影响
**变量**
- 固定:总处理器数 = 16
- 改变MPI/OpenMP组合
- 1 MPI进程 × 16 OpenMP线程
- 2 MPI进程 × 8 OpenMP线程
- 4 MPI进程 × 4 OpenMP线程
- 8 MPI进程 × 2 OpenMP线程
- 16 MPI进程 × 1 OpenMP线程
- 测试:不同矩阵尺寸 512, 1024, 2048, 4096
**测量指标**
- 运行时间ms
- 加速比 = T_serial / T_parallel
- 效率 = 加速比 / 总处理器数
## 数据处理与绘图
### 输出文件格式
**串行结果** (`serial_results.csv`):
```csv
M,N,K,Time_ms
512,512,512,123.45
1024,1024,1024,987.65
...
```
**并行结果** (`experiment_results.csv`):
```csv
Experiment,M,N,K,MPI_Processes,OpenMP_Threads,Time_ms,Speedup,Efficiency
Exp1,512,512,512,1,1,120.34,1.0267,1.0267
Exp1,512,512,512,2,1,65.43,1.8873,0.9437
...
```
### 绘图建议
使用Python (matplotlib)、Excel或R进行绘图
#### 图1实验一 - MPI进程数扩展性
- X轴MPI进程数
- Y轴加速比左轴、效率右轴
- 不同线条:不同矩阵尺寸
- 预期:加速比随进程数增加,但效率可能下降
#### 图2实验二 - 总处理器数扩展性
- X轴总处理器数
- Y轴加速比左轴、效率右轴
- 不同线条不同OpenMP线程数
- 预期混合并行可能比纯MPI或纯OpenMP更高效
#### 图3实验三 - MPI/OpenMP组合影响
- X轴MPI进程数
- Y轴效率
- 不同线条:不同矩阵尺寸
- 预期存在最优的MPI/OpenMP组合
### Python绘图示例
```python
import pandas as pd
import matplotlib.pyplot as plt
# 读取数据
df = pd.read_csv('experiment_results.csv')
# 实验一MPI扩展性
exp1 = df[df['Experiment'] == 'Exp1']
fig, ax1 = plt.subplots(figsize=(10, 6))
for size in exp1['M'].unique():
data = exp1[exp1['M'] == size]
ax1.plot(data['MPI_Processes'], data['Speedup'],
marker='o', label=f'{size}x{size}')
ax1.set_xlabel('MPI进程数')
ax1.set_ylabel('加速比')
ax1.set_title('实验一MPI进程数扩展性OpenMP=1')
ax1.legend()
ax1.grid(True)
plt.savefig('exp1_speedup.png')
plt.show()
```
## 性能分析与优化
### 预期性能瓶颈
1. **通信开销**MPI通信在大规模并行时可能成为瓶颈
2. **负载不均衡**:带状分块可能导致某些进程工作量较大
3. **内存带宽**:矩阵乘法是内存密集型操作
4. **缓存利用率**:小矩阵可能无法充分利用缓存
### 可能的优化方向
1. **优化分块策略**
- 使用二维块循环分块代替带状分块
- 考虑缓存友好的分块大小
2. **优化通信**
- 使用非阻塞通信重叠计算和通信
- 减少通信次数,增加每次通信的数据量
3. **优化计算**
- 使用SIMD指令向量化
- 优化循环顺序以提高缓存命中率
- 考虑使用Strassen算法等快速矩阵乘法
4. **混合并行优化**
- 找到最优的MPI/OpenMP组合
- 考虑NUMA架构的亲和性
## 实验报告要点
1. **实验环境**
- 硬件配置CPU核心数、内存大小
- 软件环境MPI版本、编译器版本
2. **实验结果**
- 三个实验的数据表格
- 性能曲线图
- 加速比和效率分析
3. **结果分析**
- 不同并行策略的性能比较
- MPI进程数和OpenMP线程数的最优组合
- 矩阵规模对并行效率的影响
4. **优化方案**
- 识别性能瓶颈
- 提出优化策略
- 实施优化并对比效果
5. **结论**
- MPI-OpenMP混合并行的优势
- 最佳实践建议
- 进一步改进方向
## 故障排除
### 编译错误
如果遇到MPI相关错误
```bash
# 检查MPI是否安装
which mpic++
mpic++ --version
# 检查OpenMP支持
echo | clang++ -x c++ - -fopenmp -E - > /dev/null
```
### 运行时错误
如果遇到MPI运行错误
```bash
# 检查MPI进程数是否合理
# 确保系统有足够的资源
# 检查OpenMP线程数设置
echo $OMP_NUM_THREADS
```
### 性能异常
如果性能不如预期:
1. 检查CPU频率是否正常是否降频
2. 关闭其他占用资源的程序
3. 检查系统负载
4. 确认编译优化选项已启用(-O3
## 参考资料
- MPI教程https://mpitutorial.com/
- OpenMP官方文档https://www.openmp.org/
- 并行编程模式https://patterns.eecs.berkeley.edu/