原始作业脚本
测试五轮中位数
优化后的脚本
测试五轮中位数
硬件与二进制不变
单次作业耗时减少
五轮结果波动
稳定复现
测试使用同一台双路 AMD EPYC 节点、同一个 portable AVX2 编译版本、相同输入和 96 个 MPI ranks。优化后五轮耗时为 144.8477、144.6051、145.0824、146.2305 和 145.1153 秒;中位数为 145.0824 秒,CV 为 0.4299%。
五轮均正常结束,最终能量、电子迭代轨迹以及逐 rank 的 CPU、NUMA 和内存绑定检查一致。测试过程中没有更换硬件或编译版本,也没有挑选单次最快成绩。
总来的来说,在小算子,双CPU节点上可以得到稳定收益。
144.8477 144.6051 145.0824 146.2305 145.1153
分两类控制方法,第一类控制 96 个 ranks 怎样进入计算节点;第二类控制它们落在哪颗 CPU、哪个物理核以及哪个 NUMA 内存域。
让 ranks 通过已经验证的 Slurm task step 启动。
明确每个 rank 最终对应的物理核。
作业能放进单颗 CPU 时,避免无意义地跨两路。
让内存页尽量留在 rank 所在的 NUMA 节点。
这台节点的每个 socket 有 96 个物理核。我们保持 Slurm 启动方式不变,只比较 96 个 ranks 紧凑放在单个 socket,和跨两个 socket 均衡分布。
| 放置方式 | 五轮原始值(秒) | 中位数 | CV |
|---|---|---|---|
| 单路紧凑 | 144.8477 / 144.6051 / 145.0824 / 146.2305 / 145.1153 | 145.0824 | 0.4299% |
| 双路均衡 | 168.8116 / 169.3756 / 170.2112 / 169.5997 / 170.9768 | 169.5997 | 0.4884% |
双路均衡的五轮中位数为 169.5997 秒,单路紧凑为 145.0824 秒,耗时下降 14.46%。对这个能够装入单颗 CPU 的小算例,较短的通信路径和本地内存访问更合适。
单路方案还能空出另一颗 CPU 承载其他作业。只有当内存容量或并行规模超过单路上限时,才需要把作业铺到两路。
我们固定编译方式、输入、96-rank CPU map、本地内存策略和计算轨迹,只改变启动路径。direct MPI 三轮均值为 150.8322 秒;改用 srun --mpi=pmi2 task step 后,三轮均值为 145.5949 秒,耗时下降 3.47%。
这组数据比较的是两套完整启动协议。它证明 launcher、PMI、Slurm task step 和 cgroup 会影响最终速度。
以下配置方法适用于单节点、纯 MPI、Intel MPI 和 Slurm,并且 96 个 ranks 能够完整放进一个 socket 的情况。先确认 PMI2 和 CPU 拓扑,再修改分区、socket 与 VASP 路径。
#!/usr/bin/env bash
#SBATCH --job-name=vasp-96r
#SBATCH --partition=YOUR_PARTITION
#SBATCH --nodes=1
#SBATCH --ntasks=96
#SBATCH --exclusive
#SBATCH --time=01:00:00
set -euo pipefail
# ===== 提交前修改这三处 =====
NRANKS=96
SOCKET_ID=0
VASP_LAUNCH=/path/to/site-validated-vasp-launch-command
# 单节点纯 MPI:每个 rank 使用一个线程
export OMP_NUM_THREADS=1
export MKL_NUM_THREADS=1
export MKL_DYNAMIC=FALSE
# 节点内共享内存通信,通过 Slurm PMI2 启动
export I_MPI_FABRICS=shm
export I_MPI_PMI=pmi2
# 关闭 Intel MPI 二次绑核,由 Slurm 统一负责
export I_MPI_PIN=0
export I_MPI_PIN_RESPECT_CPUSET=1
# 从指定 socket 中选择互不重复的物理核
CPU_MAP=$(
lscpu -p=CPU,CORE,SOCKET,NODE |
awk -F, -v socket="$SOCKET_ID" -v limit="$NRANKS" '
$1 !~ /^#/ && $3 == socket && count < limit && !seen[$2]++ {
print $1
count++
}
' |
paste -sd, -
)
# CPU 数量必须与 MPI ranks 一致
MAP_COUNT=$(printf '%s\n' "$CPU_MAP" | awk -F, '{print NF}')
if [ "$MAP_COUNT" -ne "$NRANKS" ]; then
echo "错误:socket ${SOCKET_ID} 只找到 ${MAP_COUNT} 个物理核,需要 ${NRANKS} 个。" >&2
exit 1
fi
echo "使用 socket:${SOCKET_ID}"
echo "MPI ranks:${NRANKS}"
echo "CPU map:${CPU_MAP}"
unset SLURM_CPUS_PER_TASK
srun --mpi=pmi2 \
--nodes=1 \
--ntasks="$NRANKS" \
--cpu-bind="verbose,map_cpu:${CPU_MAP}" \
--mem-bind=verbose,local \
--kill-on-bad-exit=1 \
"$VASP_LAUNCH" --partition:填写实际使用的 Slurm 分区;集群如果要求账户,再增加 #SBATCH --account=YOUR_ACCOUNT。SOCKET_ID:选择要使用的 socket。本文节点使用 socket 0,但其他服务器必须以 lscpu 输出为准。VASP_LAUNCH:填写本站已经验证可运行的 VASP 二进制或启动包装脚本路径。--cpu-bind=verbose 应显示 96 个 ranks 分别落在 96 个不同的物理核,并且都属于同一个 socket。--mem-bind=verbose,local 应显示每个 rank 使用本地 NUMA 内存策略。LOOP+ real time 的中位数与 CV。适用范围:脚本中的 I_MPI_FABRICS=shm 仅适用于单节点纯 MPI。跨节点、GPU 或 MPI/OpenMP 混合任务需要重新设置。现有 MPI 软件栈如果没有通过 PMI2 检查,应继续使用本站已经验证可用的启动方式。
适用范围:本文数字仅对应当前双路 AMD EPYC 节点、VASP 6.5.1、BTO 小算例、96 MPI ranks 和单节点纯 MPI。更大体系、混合 MPI/OpenMP、GPU 或跨节点任务可能得到不同结果。
版权声明:本文测试、文字及图表由慧为计算机原创。欢迎非商业转载与技术交流,转载请保留作者、原文链接及完整测试条件;商业转载或内容改编请事先联系office@cshuiwei.com授权。
欢迎查看更多:科学计算解决方案 | 高性能计算集群设计
慧为计算机致力于提供合理的高性能计算应用解决方案及IT集成项目建设的咨询。我们将面向客户提供一流的售前售后服务与可靠的产品质量。
©Copyright 2022. 长沙慧为计算机科技有限公司.