我想利用 AWS 中的所有内核 (48( 来运行我的作业。我有 600 万个列表要运行,每个作业运行不到一秒 [实际 0m0.004s 用户 0m0.005s sys 0m0.000s]。我的以下执行使用所有内核,但不是 100%。
gnu_parallel -a list.lst --load 100% --joblog process.log sh job_run.sh {} >>score.out
job_run.sh
#!/bin/bash
i=$1
TMP_DIR=/home/ubuntu/test/$i
mkdir -p $TMP_DIR
cd $TMP_DIR/
m=`echo $i|awk -F '-' '{print $2}'`
n=`echo $i|awk -F '-' '{print $3}'`
cp /home/ubuntu/aligned/$m $TMP_DIR/
cp /home/ubuntu/aligned/$n $TMP_DIR/
printf '%s ' "$i"
/home/ubuntu/test/prog -s1 $m -s2 $n | grep 'GA'
cd $TMP_DIR/../
rm -rf $TMP_DIR
exit 0
你的问题是GNU Parallel的开销:启动一个作业需要5-10毫秒。所以你可能会看到 GNU Parallel 在一个内核上以 100% 的速度运行,但其余的都是空闲的。
但是你可以运行多个 GNU Parallels:https://www.gnu.org/software/parallel/man.html#EXAMPLE:-Speeding-up-fast-jobs
因此,将列表拆分为较小的块并并行运行它们:
cat list.lst | parallel --block 100k -q -I,, --pipe parallel --joblog process.log{#} sh job_run.sh {} >>score.out
这应该运行 48+1 GNU Parallels,所以它应该使用你所有的内核。您的大部分内核将用于开销,因为您的作业非常快。
如果您不使用process.log
,则可以以较少的开销完成:
perl -pe 's/^/sh job_run.sh /' list.lst | parallel --pipe --block 100k sh >>score.out
这将在每行前面加上sh job_run.sh
,并为并行运行的 48 sh
s 提供 100kb 的行。