EDA 仿真任务调度:LSF 队列配置与大回归任务资源调优

一次全回归动辄几千个 case,每个 case 跑几小时、吃几十 GB 内存,还要占 license。没有调度,服务器会被第一个提交的人打满,其他人只能干等;有了调度,license 和算力才能排上队。这篇讲 LSF 下 EDA 负载的队列划分、提交姿势和调优。

一、EDA 负载的特点

  • 长任务:一个 case 几小时到几天,短任务和调试要走别的队列,不能混在一起。
  • 内存大:仿真吃内存是常态,内存申请少了会被 OOM kill,多了浪费。
  • license 绑定:没 license 的任务跑起来也是空等,要在调度层感知 license。
  • IO 密集:波形、log、中间文件多,存储带宽是隐形瓶颈。

二、队列怎么分

一般分三层:interactive 队给短任务和交互调试用,限制时间和并发;batch 队是回归主力,按项目或工具再分,比如 vcs_regress、zebu_run;优先级上日常回归低于流片前回归,紧急 debug 最高,靠优先级和 fairshare 调。关键项目要做预留:给流片前的关键回归预留一部分节点和 license,避免被长尾任务占满。

# lsb.queues 片段:回归队列示例
Begin Queue
QUEUE_NAME   = vcs_regress
DESCRIPTION  = VCS 回归队列
PRIORITY     = 30
RUN_WINDOW   = 0:00-24:00
HOSTS        = simfarm
RES_REQ      = rusage[mem=8192]
End Queue

三、提交姿势(bsub 常用组合)

# 提交一个仿真任务:4 核、32G 内存上限、每核 8G
bsub -q vcs_regress -n 4 -M 32768 -R "rusage[mem=8192]" \
  -o run.%J.log -e run.%J.err -J "regress_case_042" ./run_case.sh

# 依赖:前一个综合完了,后一个仿真再跑
bsub -q vcs_regress -w "done(synth_job)" ./run_sim.sh

# 数组任务:一次提交 500 个 case,用索引取参数
bsub -q vcs_regress -J "case[1-500]" ./run_case.sh $LSB_JOBINDEX

几个习惯:-o、-e 指定 log,别让默认 log 淹没 home 目录;-J 起个能看懂的名字,查任务时一眼定位;-M 是内存上限,超了就被杀,宁可先估大一点再收紧。

四、license 感知调度

把 license 当资源申:bsub -R "rusage[lic_vcs=1]",调度器按 license 余量放任务。原理很简单:license 数量是硬上限,超发只会让任务在工具启动时失败,白白占着节点。配额按项目组分池子,超了就排队,别互相抢。

五、排队与公平性

  • fairshare:按项目组配额动态调优先级,用得多的人自动降权,避免一家独占。
  • 预留(reservation):流片前给关键回归预留节点和 license,提前锁定资源。
  • 抢占:紧急任务可以抢占低优先级任务,要配好,别误伤跑了十几小时的长任务。

六、排障速查

# 看任务状态和挂起原因
bjobs
bjobs -p <jobid>        # PEND 的原因

# 看任务历史和结束原因
bhist -l <jobid>

# 看队列和节点状态
bqueues
bhosts

任务被杀先看 bhist -l 和 log,内存超限(MEMLIMIT)是最常见的死因;挂起多数是资源不够,对着 bjobs -p 的原因逐项查;跑得慢先看是不是被邻居任务抢了内存带宽,再看存储。

调度的本质是排队论:让正确的任务在正确的时间拿到正确的资源。队列分好、资源申准、license 感知做好,大回归就能稳稳地跑。

发表回复

后才能评论