前言
搭建好 HPC 集群并确认服务健康后,下一步就是”跑分”。基准测试(Benchmarks)不仅是评估系统性能的标尺,更是验证软硬件协同(如 GPU 加速、InfiniBand 网络、MPI 通信)是否达到最佳状态的试金石。
本篇将基于 IBM Spectrum LSF 环境,手把手教您如何编译和提交三大核心基准测试:
| 基准测试 | 测量指标 | 应用场景 |
|---|---|---|
| HPL | 浮点计算能力 (Gflops) | TOP500 排名、GPU 验证 |
| OSU | 网络延迟与带宽 | MPI 通信、GPU Direct RDMA |
| STREAM | 内存带宽 (GB/s) | 内存子系统性能 |
注意:本文示例基于 IBM POWER9 AC922 服务器、NVIDIA V100 GPU 和 IBM Spectrum MPI 环境。但在 x86(如 NVIDIA DGX)或 ARM 架构上,方法论和 LSF 提交逻辑是通用的。
一、HPL (Highly Parallel LINPACK):算力的黄金标准
HPL 是全球超算 TOP500 排名的基准测试,用于测量系统的浮点计算能力。
1. 关键准备工作
在运行 HPL 之前,尤其是涉及 GPU 时,必须确认以下组件已就绪:
基础环境
| 组件 | 版本要求 |
|---|---|
| CUDA Toolkit | 10.1+ |
| ESSL | 数学库 |
| GCC | 编译器 |
| Spectrum MPI | 10.3+ |
GPU Direct 支持
如果使用 InfiniBand,必须安装并加载 nvidia_peer_mem 和 nvidia_rsync 内核模块,以支持 GPU 显存与 IB 网卡的直接数据传输。
1
2
3
4
5
# 验证 GPU Direct 内核模块
$ lsmod | grep nv
nv_peer_mem 16384 0
nvidia_uvm 856064 0
nvidia 20385792 2 nvidia_uvm,nv_peer_mem
输出中应包含 nv_peer_mem 和 nv_rsync_mem。
网络优化
对于多 Socket 系统,建议设置 PAMI 环境变量来绑定特定 Socket 到对应的 IB 网口:
1
export PAMI_IBV_DEVICE_NAME=mlx5_0:1
2. 玩转 HPL.dat:N, P, Q 的数学题
HPL 的输入配置文件 HPL.dat 决定了测试规模。核心参数计算规则如下:
问题规模 (N)
计算公式:
\[\text{占用内存 (Bytes)} = 8 \times N \times N\]| 规则 | 说明 |
|---|---|
| 建议值 | 占用物理内存的 85% - 90% |
| 限制条件 | N 必须是整数,且 N 除以块大小(NB=768)必须是整数 |
| 示例 | 1TB 内存节点,N 可设为 307200 |
进程网格 (P × Q)
计算公式:
\[P \times Q = \text{使用的 GPU 总数}\]| 规则 | 说明 |
|---|---|
| Q ≥ P | P 和 Q 尽量接近 |
| Q 限制 | 必须是 RANKS_PER_SOCKET 的倍数 |
| 示例 | 4 节点 × 4 GPU = 16 GPU,设 P=4, Q=4 |
3. LSF 作业提交脚本
不要手动运行 mpirun,让 LSF 来管理资源绑定。以下是一个针对 2 个节点、8 张 GPU 的提交脚本示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/bash
#BSUB -cwd /path/to/hpl
#BSUB -gpu "num=4:mode=exclusive_process:mps=no" # 每个节点申请4个GPU
#BSUB -J HPL-8tasks
#BSUB -n 8 # 总共8个任务
#BSUB -o hpl.%J.log
#BSUB -q lewen
#BSUB -R "affinity[core(10):span[ptile=4]]" # 核心亲和性绑定
#BSUB -x # 独占节点
# 环境变量设置
export RANKS_PER_NODE=4
export OMP_NUM_THREADS=$CPU_CORES_PER_RANK
# HPL 优化参数
export GPU_DGEMM_SPLIT=1.0
export GPU_DGEMM_ENABLE=1
export MONITOR_GPU=1
# 运行命令
ulimit -c 0
source /opt/ibm/spectrum_mpi/smpi.sh
mpirun --report-bindings -prot ./xhpl_spectrum_10.1
结果验证
检查输出文件中的关键信息:
1
2
3
4
5
6
================================================================================
T/V N NB P Q Time Gflops
--------------------------------------------------------------------------------
WR11C2R4 307200 768 4 4 1234.56 1.234e+05
--------------------------------------------------------------------------------
||Ax-b||_oo/(eps*(||A||_oo*||x||_oo+||b||_oo)*N)= 0.0012345 ...... PASSED
建议:从单节点开始测试,逐步扩展节点数,观察并行效率。
二、OSU Micro-benchmarks:网络性能体检
OSU 微基准测试主要用于评估 MPI 操作的延迟和带宽,特别是测试 GPU Direct RDMA 是否生效。
1. 编译与配置
下载 OSU 源码后,需配置 MPI 编译器并开启 CUDA 支持:
1
2
3
4
5
./configure CC=mpicc CXX=mpicxx \
--enable-cuda \
--with-cuda-include=/usr/local/cuda/include \
--with-cuda-libpath=/usr/local/cuda/lib64
make && make install
2. 关键测试项目
我们重点关注点对点 (Point-to-Point) 测试:
| 测试程序 | 功能 | 说明 |
|---|---|---|
osu_latency |
单向延迟 | 越低越好 |
osu_bw |
单向带宽 | 越高越好 |
osu_bibw |
双向带宽 | 测试全双工性能 |
Device (D) 支持
OSU 支持测试不同内存位置之间的通信:
| 模式 | 含义 |
|---|---|
H H |
Host-to-Host(主机内存) |
D D |
Device-to-Device(GPU 显存直接通信) |
H D |
Host-to-Device |
3. LSF 提交实战
创建一个提交脚本 osu_lsf_job_submission.sh,申请 2 个节点进行 Ping-Pong 测试:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash
#BSUB -n 2
#BSUB -R "affinity[core(1):distribute=balance] span[ptile=1]" # 每个节点1个任务
#BSUB -gpu "num=1:mode=exclusive_process"
#BSUB -J osu_test
#BSUB -o osu.%J.log
source /opt/ibm/spectrum_mpi/smpi.sh
echo "=== Host-to-Host Bandwidth Test ==="
mpirun --report-bindings -prot osu_bibw
echo "=== GPU-to-GPU (Device-to-Device) Bandwidth Test ==="
# D D 表示发送和接收缓冲区都在 GPU 显存上
mpirun -gpu --report-bindings -prot osu_bibw D D
结果分析
1
2
3
4
5
# OSU MPI-CUDA Bi-Directional Bandwidth Test
# Size Bandwidth (MB/s)
1048576 23456.78
2097152 24567.89
4194304 25000.00
如果配置正确,GPU Direct RDMA (D D) 的带宽应接近物理链路极限(如 HDR InfiniBand 理论 200 Gb/s),且延迟极低。
三、STREAM Benchmark:内存带宽大考
STREAM 用于测量可持续的内存带宽,对于评估计算密集型应用的数据吞吐能力至关重要。
1. 数组大小设置
STREAM 的核心在于 Array_Size:
| 规则 | 说明 |
|---|---|
| 总内存需求 | 至少是 CPU 总缓存大小的 10 倍 |
| 公式 | 内存占用 = 8 × Array_Size × 3 |
| 目的 | 确保测试的是主存而非缓存性能 |
2. 编译
使用 OpenMP 进行并行加速:
1
2
3
4
gcc -O3 -fopenmp \
-DSTREAM_ARRAY_SIZE=900000000 \
-DNTIMES=10 \
stream.c -o stream.gcc
3. LSF 提交与 OpenMP
在 LSF 脚本中,需要利用 -a openmp 选项或手动设置 OMP_NUM_THREADS:
1
2
3
4
5
6
7
8
9
#!/bin/bash
#BSUB -n 1
#BSUB -R "affinity[core(36):distribute=balance] span[ptile=1]" # 申请整个节点的核
#BSUB -a openmp
#BSUB -J stream_test
#BSUB -o stream.%J.log
#BSUB -m lewen11 # 指定特定节点测试
./stream.gcc
预期输出
1
2
3
4
5
6
7
-------------------------------------------------------------
Function Best Rate MB/s Avg time Min time Max time
Copy: 123456.7 0.058000 0.057800 0.058200
Scale: 123000.0 0.058500 0.058300 0.058700
Add: 130000.0 0.083200 0.083000 0.083400
Triad: 131000.0 0.082800 0.082600 0.083000
-------------------------------------------------------------
注意:确保在集群中的每一个节点上都运行一遍 STREAM 测试,以发现潜在的”短板”内存条或节点。
基准测试总结
| 测试 | 指标 | 关键配置 | LSF 要点 |
|---|---|---|---|
| HPL | Gflops | N, P, Q, NB | -gpu、affinity、独占节点 |
| OSU | 延迟/带宽 | CUDA 支持、D D 模式 | 2 节点、span[ptile=1] |
| STREAM | GB/s | Array_Size | -a openmp、全核心绑定 |
1
2
3
4
5
6
7
8
9
10
11
┌─────────────────────────────────────────────────────────────┐
│ HPC 基准测试验证流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ STREAM ───→ 验证内存子系统(每节点独立测试) │
│ ↓ │
│ OSU ─────→ 验证网络通信(H-H 和 D-D 对比) │
│ ↓ │
│ HPL ─────→ 验证整体计算能力(逐步扩展节点) │
│ │
└─────────────────────────────────────────────────────────────┘
下期预告:
跑分数据令人满意,接下来如何让业务用户用起来?如何将 TensorFlow 训练任务或 OpenFOAM 流体仿真任务集成到 LSF Web 界面中?在下一篇《IBM Spectrum LSF Suite 最佳实践 (5):应用集成实战——从 TensorFlow 到 OpenFOAM 可视化》中,我们将进入应用集成的精彩世界。