我正在尝试找到一种在集群上执行 CPU 密集型并行作业的方法。我的目标是为每个内核安排一个作业,以便每个作业在安排后都有望获得 100% 的 CPU 利用率。这是迄今为止提出的:
文件 build_sshlogin.sh
#!/bin/bash
serverprefix="compute-0-"
lastserver=15
function worker {
server="$serverprefix$1";
free=$(ssh $server /bin/bash << 'EOF'
cores=$(grep "cpu MHz" /proc/cpuinfo | wc -l)
stat=$(head -n 1 /proc/stat)
work1=$(echo $stat | awk '{print $2+$3+$4;}')
total1=$(echo $stat | awk '{print $2+$3+$4+$5+$6+$7+$8;}')
sleep 2;
stat=$(head -n 1 /proc/stat)
work2=$(echo $stat | awk '{print $2+$3+$4;}')
total2=$(echo $stat | awk '{print $2+$3+$4+$5+$6+$7+$8;}')
util=$(echo " ( $work2 - $work1 ) / ($total2 - $total1) " | bc -l );
echo " $cores * (1 - $util) " | bc -l | xargs printf "%1.0f"
EOF
)
if [ $free -gt 0 ]
then
echo $free/$server
fi
}
export serverprefix
export -f worker
seq 0 $lastserver | parallel -k worker {}
该脚本由 GNU 并行使用,如下所示:
parallel --sshloginfile <(./build_sshlogin.sh) --workdir $PWD command args {1} ::: $(seq $runs)
这种技术的问题是,如果有人在集群中的服务器上启动另一个 CPU 密集型作业,而不检查 CPU 使用情况,那么脚本最终会将作业调度到正在使用的核心。此外,如果在第一个作业完成时 CPU 使用率发生了变化,那么新释放的内核将不会被 GNU 并行调度用于剩余作业。
所以我的问题如下:有没有办法让 GNU 在调度每个作业之前并行重新计算空闲内核/服务器?欢迎任何其他解决问题的建议。
注意:在我的集群中,所有核心都具有相同的频率。如果有人可以概括以解释不同的频率,那也是受欢迎的。