有使用超算或者服务器的同学应该会接触过超算投递系统,在提交生信任务时,我们需要设置好资源,比如说cpu用多少,内存给多少。学生时代的我是有多大内存提供就设多大内存,有多少CPU数提供就设多少CPU,经过一段时间使用超算的体验发现,资源还是要合理分配才能达到最大的效率,也避免任务因为申请超额的资源而被管理员kill掉或者出现节点宕机的情况(最重要,省钱!)。
0、前言
为什么要这么做?
- 合理分配资源,避免作业因资源问题而造成拥堵
- 提高软件的效率
- 省钱
思路
- 实现
top
命令的功能并记录下来
top命令的实现实际上也是不断地到系统中的/proc/$PID/
和/proc/
目录下不断地获取与进程相关的信息并可视化相关的参数。 - 用
qacct
命令获取调度器中任务id(job)的信息
1、Nextflow资源监控模式
- 生信流程引擎Nextflow提供了监控流程中的进程资源消耗的功能,通过下面的命令打卡监控模式;
- 流程运行的过程中不可能每时每刻都使用top命令查看流程中的每个进程;
- 一个流程包含多个进程,难以统计;
- HPC超算计算的服务投递之后仅返回任务的jobID,用户并不能直接获取流程中进程的ID号(相当于没办法直接获得流程中进程的PID号);
nextflow run <pipeline name> -with-trace
2、结果解读及脚本计算公式
-
nextflow资源获取结果:结果总共输出15项结果(见下图)
- 与投递资源相关的参数:%CPU和vmem(图上除了百分比的数值以外其他数据的单位均为kb)
%cpu
:进程占用 CPU 百分比
-
进程的时间
到/proc/pid/stat 这个文件中获取时间
的结果:第14列:Utime(进程在用户态运行的时间),第15列:Stime(进程在内核态运行的时间),第16列:Cutime(进程等待的子进程在用户态运行的时间),第17列:Cstime(进程等待的子进程在内核态运行的时间)
计算公式:
prev_proc_cpu_total
= utime + stime + cutime + cstime
after_proc_cpu_total
= utime + stime + cutime + cstime
下面的脚本中,如果是多核心系统还需要乘以cpu核心数
process_total_time=$(2> /dev/null < /proc/$pid/stat awk '{printf "%.0f", ($14+$15+$16+$17)*10 * cpu_num }' || echo -n 'X')
-
总CPU时间的获取
到/proc/stat获取第2列到第9列
prev_cpu_total = user + nice + system + idle + iowait + irq + softirq
after_cpu_total = user + nice + system + idle + iowait + irq + softirq
对应代码如下:
cpu_total=$(grep '^cpu ' /proc/stat |awk '{sum=$2+$3+$4+$5+$6+$7+$8+$9+$10; print sum}')
vmem
:进程使用的虚拟内存大小,这个值可以直接获取,只需进行字节的转化
3、验证方法及SGE查看计算节点资源消耗的方法
- 利用ssh和top获取计算节点上的进程信息与返回的结果进行比较(此处没截到数据),但返回的%CPU,%MEM,VMEM基本与TOP返回的结果一致。
ssh -t remotehost top -u userid #即用户名
- 有多核系统的top命令数据
如果是多核系统top命令中的%CPU会返回大于100% 的数值,说明这个任务被分配了多个CPU或者多个线程
。
- 在SGE管理集群上使用
qacct
命令获取job任务跑任务时使用的最大虚拟内存(maxvmem)
# 列出全部的job
qacct -o user -d 1 -j
# 指定job
qacct -o user -d 1 -j job_id
4、结果解析及资源分配确定
最后回答开头的问题即“到底要给一个脚本任务分配多少资源”
在qsub系统中如何设置vf(virtual_free)大小,还有smp的数量
- 换算公式
smp数量设置
vf虚拟内存大小设置
参考
SGE virtual free设置教程
top
cpu-usage-calculation
中文版解说
参考3
stackoverflow cpu%解释