SLURM:如何通过sbatch在同一节点不同核心并行运行脚本并指定核心
SLURM同节点同Socket核心并行运行脚本问题解答
问题场景
作为SLURM新手,我希望在同一节点、同一socket的不同核心上并行运行两个各需2分钟的脚本。系统每个节点包含2个socket,每个socket有10个核心。我编写了如下脚本:
#!/bin/bash #SBATCH -J script #SBATCH --time=00:05:00 #SBATCH --exclusive #SBATCH --nodes=1 #SBATCH --ntasks-per-node=2 #SBATCH --cpus-per-task=2 #SBATCH --partition=xeon #SBATCH --output=OUTPUT.txt #SBATCH --hint=nomultithread ml intel module load openmpi srun -c 1 --exclusive ./runScript1 & srun -c 1 --exclusive ./runScript2 & wait
执行后通过squeue --job [jobID]查看发现总耗时4分钟,推测脚本是串行执行的。曾尝试用taskset指定核心但出现错误,现提出两个问题:
- 我的判断或操作是否有误?
- 是否可通过
taskset或--cpu-bind选项指定特定核心运行?
问题解答
1. 你的判断和操作确实存在错误
总耗时4分钟的原因是脚本确实在串行执行,问题出在以下两点:
- srun的
--exclusive参数滥用:给每个srun都添加--exclusive,会让每个srun试图独占整个作业分配的所有资源,导致第二个srun必须等第一个执行完成才能获取资源,最终变成串行运行。 - 资源分配参数不匹配:你用
--cpus-per-task=2给每个任务分配了2个核心,但实际每个脚本只需要1个核心,资源分配冗余,同时也加剧了资源竞争问题。另外,--exclusive会占用整个节点,但你的资源参数并没有用到全部节点资源,属于不必要的配置。
2. 可以通过--cpu-bind或taskset指定特定核心运行
两种方式的正确用法如下:
方式一:使用SLURM的--cpu-bind参数
这是更贴合SLURM调度逻辑的方式,无需手动指定核心编号,让SLURM自动分配同一socket的核心,或者手动绑定到指定核心:
#!/bin/bash #SBATCH -J script #SBATCH --time=00:05:00 #SBATCH --nodes=1 #SBATCH --ntasks-per-node=2 #SBATCH --cpus-per-task=1 # 每个任务仅需1个核心,匹配脚本需求 #SBATCH --partition=xeon #SBATCH --output=OUTPUT.txt #SBATCH --hint=nomultithread # 绑定两个任务到同一个socket的核心 #SBATCH --cpu-bind=socket ml intel module load openmpi # 用srun的冒号分隔多个任务,SLURM会自动并行调度 srun ./runScript1 : ./runScript2
如果需要手动绑定到具体核心,可以先通过lscpu查看socket对应的核心编号(比如socket 0对应核心0-9),然后修改srun命令:
srun --cpu-bind=core:0 ./runScript1 & srun --cpu-bind=core:1 ./runScript2 & wait
方式二:使用taskset工具
使用taskset前,必须确保指定的核心在SLURM分配给当前作业的核心范围内(这是你之前出错的关键原因),步骤如下:
#!/bin/bash #SBATCH -J script #SBATCH --time=00:05:00 #SBATCH --nodes=1 #SBATCH --ntasks-per-node=2 #SBATCH --cpus-per-task=1 #SBATCH --partition=xeon #SBATCH --output=OUTPUT.txt #SBATCH --hint=nomultithread # 可选:先指定分配同一socket的核心 #SBATCH --cpu-bind=socket ml intel module load openmpi # 获取当前作业允许使用的核心列表 allowed_cores=$(scontrol show job $SLURM_JOB_ID | grep -oP 'Cpus=\K[^ ]+') # 从允许的核心中挑选同一socket的两个核心(比如选0和1,需确认属于同一socket) taskset -c 0 ./runScript1 & taskset -c 1 ./runScript2 & wait
内容的提问来源于stack exchange,提问作者thezbx
相关产品推荐
相关产品推荐

