Slurm作业执行时长异常波动问题排查与解决咨询
Slurm作业执行时长异常排查与修复
问题背景
我使用如下Slurm作业脚本:
#!/bin/bash #SBATCH -p cs #SBATCH -e %j.err #SBATCH --time=40:00 #SBATCH --output=slurm-%j.out #SBATCH --cpus-per-task=2 #SBATCH --nodes=1 #SBATCH --ntasks=1 # executable for I in $(seq 32) do export OMP_NUM_THREADS=2 && srun --nodes=1 --ntasks=1 --cpus-per-task=2 bash -c "./debug > ./logs/112500/exp$I/log-2.txt" done
针对不同OMP线程数,我会修改脚本头部的--cpus-per-task参数(设为对应OMP线程数),同时修改srun命令中的同名参数。手动串行提交脚本,完成一个后再提交对应更多线程的脚本,但出现异常:同一作业中的32次实验虽整体有规律,但部分任务的执行时长是常规时长的20倍甚至350倍。debug程序核心是无外部干扰的嵌套循环,仅用于测量并行程序的墙钟时间。
实验执行时长数据如下:
异常原因
- CPU资源未绑定导致竞争:脚本未明确设置CPU核心绑定策略,集群调度时可能将不同实验的线程分配到同一物理核心或共享缓存的核心上,引发资源争抢,大幅拖慢执行速度。
- 嵌套srun的调度开销:在单个Slurm作业内循环调用
srun会触发二次调度,每次srun都需要重新申请资源、初始化环境,随机延迟可能导致任务等待资源的时间远超过任务本身执行时间。 - 线程-核心不匹配与迁移:虽手动修改了
--cpus-per-task和OMP_NUM_THREADS,但未确保OMP线程固定绑定到分配的CPU核心,线程在核心间频繁迁移会带来大量上下文切换开销。
修复方案
方案1:移除嵌套srun,直接循环执行程序
利用Slurm已分配的资源,直接在作业环境中运行debug,同时添加CPU绑定策略:
#!/bin/bash #SBATCH -p cs #SBATCH -e %j.err #SBATCH --time=40:00 #SBATCH --output=slurm-%j.out #SBATCH --cpus-per-task=2 #SBATCH --nodes=1 #SBATCH --ntasks=1 # 绑定OMP线程到分配的CPU核心,避免迁移 export OMP_PROC_BIND=close export OMP_PLACES=cores # 自动关联Slurm分配的CPU数,避免手动修改出错 export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK # executable for I in $(seq 32) do ./debug > ./logs/112500/exp$I/log-2.txt done
方案2:用srun批量调度所有任务(适合并行执行)
如果需要并行完成32次实验,可让srun直接调度所有任务,同时确保资源独占:
#!/bin/bash #SBATCH -p cs #SBATCH -e %j.err #SBATCH --time=40:00 #SBATCH --output=slurm-%j.out #SBATCH --cpus-per-task=2 #SBATCH --nodes=1 #SBATCH --ntasks=32 # 对应32次实验 export OMP_PROC_BIND=close export OMP_PLACES=cores export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK # 批量调度每个实验,--exclusive确保任务独占分配的CPU资源 srun --ntasks-per-node=32 --exclusive bash -c "./debug > ./logs/112500/exp$SLURM_PROCID/log-2.txt"
额外优化建议
- 始终用
$SLURM_CPUS_PER_TASK设置OMP_NUM_THREADS,避免手动修改时出现参数不匹配。 - 作业头部添加
#SBATCH --exclusive,确保当前作业独占节点资源,避免其他作业干扰。 - 若集群支持,可直接用
#SBATCH --cpu-bind=cores指定全局CPU绑定策略。
内容的提问来源于stack exchange,提问作者selinnilesy
相关产品推荐
相关产品推荐

