PAYATHON 2026

如何确定 Slurm job 应计费的总 core hours?

支付老李

结论

通常都不是。

3591397 是整个作业的资源分配记录,3591397.batch 和 3591397.0 则是该作业内部的 job step。它们可能同时运行,也可能互相嵌套,所以不能把三行的时间相加,也不能只累加两个 step 的时间。

暂不考虑内存、GPU 和其他计费权重时,CPU 核时通常按下面的公式计算:

[ \text{core hours}=\text{作业分配的 CPU 数}\times\text{作业占用资源的时间(小时)} ]

计算时主要看顶层作业 3591397 的 AllocCPUS 和 Elapsed,不要累加 .batch 和 .0 的运行时间。

这三行分别表示什么

一次典型的 sbatch 作业在 sacct 中可能显示为:

3591397
3591397.batch
3591397.0

各行通常表示:

  • 3591397:顶层作业,对应调度器为该作业保留的资源。
  • 3591397.batch:运行批处理脚本的 batch step。
  • 3591397.0:脚本中第一次执行 srun 时创建的 job step。
  • 后续执行的 srun 可能显示为 .1、.2 等。

这三条记录并不代表三个相互独立的资源分配。.batch 和 .0 都属于 3591397,它们的运行时间一般已经包含在顶层作业的生命周期中。如果将这些时间相加,就会重复计算。

如何计算 core hours

先查看顶层作业的相关字段:

sacct -j 3591397 \
  --format=JobID,State,AllocCPUS,Elapsed,ElapsedRaw,CPUTimeRAW,TotalCPU

假设输出如下:

JobID           AllocCPUS    Elapsed    ElapsedRaw    CPUTimeRAW
3591397                 16   01:45:00          6300        100800
3591397.batch            1   01:44:50          6290          6290
3591397.0               16   01:30:00          5400         86400

顶层作业分配了 16 个 CPU,占用资源 1 小时 45 分钟,因此:

[ 16\times1.75=28\text{ core hours} ]

也可以用原始秒数计算:

[ \frac{\text{AllocCPUS}\times\text{ElapsedRaw}}{3600}

\frac{16\times6300}{3600}

28 ]

对于普通作业,顶层记录中的 CPUTimeRAW 通常近似等于:

AllocCPUS × ElapsedRaw

可以通过下面的命令查看:

sacct -n -X -j 3591397 \
  --format=JobIDRaw,AllocCPUS,ElapsedRaw,CPUTimeRAW

再按下面的公式换算:

[ \text{core hours}=\frac{\text{CPUTimeRAW}}{3600} ]

参数 -X 只显示作业分配记录,隐藏 .batch、.extern 和数字编号的 job step,可以减少误读。

CPUTimeRAW 和 TotalCPU 不一样

这两个字段含义不同:

  • CPUTimeRAW:分配的 CPU 数乘以经过时间,单位是 CPU-seconds,更接近按资源占用量计算的核时。
  • TotalCPU:所有进程实际消耗的 user CPU time 与 system CPU time 之和,反映实际计算量。

例如,某个作业分配了 16 个 CPU,但程序大部分时间只使用一个 CPU:

CPUTimeRAW = 16 × 作业运行秒数
TotalCPU   ≈ 1 × 实际忙碌秒数

多数 HPC 中心按照为作业预留或分配的资源计费,而不是按照 TotalCPU 计费,因为其他用户通常无法在这段时间内使用这些资源。具体仍要以集群本地的计费策略为准。

需要特别确认的情况

以下情况可能导致实际账单与简单的 AllocCPUS × Elapsed 计算结果不同:

  • 集群按节点数、GPU、内存或 TRES billing weight 计费。
  • 作业独占整个节点,即使只申请了部分 CPU,也可能按整节点计费。
  • srun 创建了额外的资源分配,而不是父作业内部的普通 step。
  • 作业数组、异构作业或多个独立 job ID 需要分别计算。
  • 集群对暂停时间、失败作业、启动时间或最短计费时长另有规定。
  • 管理员采用 TRESBillingWeights 或外部计费系统,而不是直接使用 CPUTimeRAW。

如果集群记录了 billing TRES,可以查看:

sacct -j 3591397 \
  --format=JobID,Account,Partition,AllocCPUS,Elapsed,AllocTRES%50

对于问题中的普通 sbatch 加单个 srun 场景,应以顶层 3591397 的资源分配为准,只计算一次,不要累加 3591397.batch 和 3591397.0。最终应付金额或计费额度,还需要按照所在 HPC 中心的本地 billing policy 计算。

备注:内容仅供参考。