GNU与for循环功能并行

时间:2019-04-24 21:34:53

标签: bash parallel-processing gnu-parallel

我想利用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

1 个答案:

答案 0 :(得分:2)

您的问题是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并行运行的行提供100kb的行。