3. 并行调度基础与评价指标

参数扫描任务一旦从“单机顺序跑”升级为“多机并行跑”,调度器就必须回答三个问题:先跑谁、放到哪、什么时候算跑完。这三个问题分别对应调度目标、约束条件和问题分类。本节围绕大型参数扫描这一具体场景,把调度目标(makespan、吞吐量、资源利用率)、约束条件(CPU/GPU/内存/IO)和调度问题分类讲清楚,为后续的调度算法设计打基础。

一、三个核心调度目标

Makespan(完工时间)指从第一个任务开始执行到最后一个任务结束所经历的时间,即整批扫描的“墙钟时间”。它是参数扫描最直观的目标:用户提交 500 组参数,最关心的是“多久能全部跑完”。makespan 由关键路径决定——即使大部分机器空闲,只要有一个长任务还在跑,makespan 就不会缩短。因此缩短 makespan 的关键是让长任务尽早开始,并尽量把长任务与短任务搭配填充。

吞吐量(Throughput)指单位时间内完成的任务数,常用“任务/小时”度量。它与 makespan 相关但不完全等价:当任务长度差异很大时,追求高吞吐量意味着优先让机器保持忙碌、减少空转,而不一定让整批最早结束。例如一批任务中有 1 个耗时 10 小时的大任务和 99 个耗时 10 分钟的小任务,若先跑大任务,makespan 约为 10 小时出头;若先跑小任务,大任务最后才开始,makespan 可能接近 11 小时,但前 10 小时内吞吐量很高。调度策略必须明确当前优化的是哪一个。

资源利用率指资源被有效使用的时间占比,如 CPU 利用率 = 累计 CPU 忙碌时间 / (机器数 × makespan)。参数扫描中常见的浪费是“等资源”:任务已就绪,但因内存不足或 GPU 被占而排队。利用率低往往意味着约束条件没有被合理匹配,而不是任务不够多。

三个目标存在权衡:一味追求高利用率可能拉长 makespan(把短任务塞满导致长任务推迟);一味追求短 makespan 可能让部分机器在收尾阶段空闲。实际调度器通常以 makespan 为主目标,把吞吐量和利用率作为约束或次要指标。

二、约束条件:四类资源的匹配关系

参数扫描任务的资源需求差异很大:有的任务只吃 CPU(如数据预处理、轻量数值计算),有的必须占 GPU(如深度学习训练),有的内存占用高(如大矩阵运算),有的 IO 密集(如频繁读写中间结果)。调度器必须为每个任务记录资源需求向量,并在分配时同时满足所有维度。

以一台 8 核 CPU、1 块 GPU(显存 24 GB)、64 GB 内存的节点为例,一个任务声明 cpu=4, gpu=1, mem=32GB,则同一节点最多同时容纳 2 个此类任务(CPU 和内存都恰好用满),GPU 成为第三个任务的瓶颈。若任务声明 cpu=2, gpu=0, mem=8GB,则可与 GPU 任务共存,实现 CPU 与 GPU 的互补填充——这正是提高利用率的关键手段。

IO 约束常被忽视。当多个任务同时读写同一块共享存储时,带宽会被摊薄,单个任务的实际耗时可能远高于预期。调度器若能把 IO 密集任务在时间上错开,或限制单节点并发 IO 任务数,就能避免“资源看似空闲、任务却变慢”的假象。

三、调度问题分类

从调度理论看,参数扫描调度属于多机、多资源约束、任务长度已知或可估计、任务间无依赖的调度问题。按任务长度是否可预知,分为确定性调度(已知每个任务预计耗时,可用 LPT 等启发式)和在线调度(任务陆续到达、长度未知,需动态决策)。按是否允许抢占,分为非抢占(任务一旦开始必须跑完,参数扫描通常如此)和可抢占(可中断后恢复,需检查点支持)。按资源维度,分为单资源和多维资源问题;参数扫描几乎总是多维的,属于 NP 难的组合优化问题,实际系统多采用启发式或元启发式求解。

参数扫描并行调度的目标—约束—分类关系 调度目标 Makespan:整批完工时间 吞吐量:单位时间完成数 利用率:资源忙碌占比 约束条件(多维资源) CPU 核数 GPU 卡数 / 显存 内存容量 IO 带宽(共享存储) 问题分类 确定性 / 在线调度 抢占 / 非抢占 单资源 / 多维资源 NP 难 → 启发式求解 决定 建模 示例:4 个任务在 2 台机器上的两种分配(任务耗时:A=6h, B=4h, C=3h, D=2h) 方案一(顺序填充) M1 A 6h C 3h M2 B 4h D 2h makespan = 9h 方案二(LPT 长任务优先) M1 A 6h D 2h M2 B 4h C 3h makespan = 8h 方案二把长任务 A 与短任务 D 搭配,使两台机器负载更均衡,makespan 缩短 1 小时

四、用示例算一遍指标

假设有 4 个参数扫描任务,预计耗时分别为 A=6h、B=4h、C=3h、D=2h,运行在 2 台同构机器上,任务不可抢占、无依赖。方案一按提交顺序分配:M1 跑 A 再跑 C(6+3=9h),M2 跑 B 再跑 D(4+2=6h),makespan=9h,平均利用率=(9+6)/(2×9)=83.3%。方案二采用 LPT(Longest Processing Time first,最长任务优先):先排 A 到 M1,再排 B 到 M2,C 排到当前负载较轻的 M2(4+3=7h),D 排到 M1(6+2=8h),makespan=8h,利用率=(8+7)/(2×8)=93.75%。同一批任务,仅调整分配顺序,makespan 缩短 1 小时、利用率提升约 10 个百分点——这就是调度目标与约束匹配带来的直接收益。

需要说明的是,上述数值为教学示例中的假设参数,用于说明指标计算与分配逻辑,并非实际集群实测结果。真实环境中任务耗时会波动,调度器通常用历史运行数据估计任务长度,并预留安全余量。

五、实践中的判断依据

在实现或选型调度器时,建议先明确主目标:若用户最关心“整批何时结束”,以 makespan 为主,采用 LPT 类启发式并优先启动长任务;若系统面向持续提交的扫描流,则以吞吐量为先,保持机器高占用、减少空转。约束建模上,务必把 CPU、GPU、内存、IO 作为独立维度记录,分配时逐维校验,避免“CPU 够但内存不够”导致的无效调度。分类上,参数扫描多为非抢占、多维资源、NP 难问题,不必追求最优解,启发式加动态回填(backfilling)通常已能获得接近最优的效果。评价时同时记录 makespan、吞吐量和各资源利用率,三者结合才能判断调度策略是否真正适配当前负载。