GNU параллельно с для функции цикла - PullRequest
2 голосов
/ 25 апреля 2019

Я хотел бы использовать все ядра (48) в AWS для запуска своей работы.У меня есть 6 миллионов списков для запуска, и каждое задание выполняется менее чем за секунду [реальный пользователь 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 Ответ

2 голосов
/ 25 апреля 2019

Ваша проблема связана с издержками GNU Parallel: запуск задания занимает 5-10 мс. Таким образом, вы, вероятно, увидите, что GNU Parallel работает на 100% на одном ядре, а остальные бездействуют.

Но вы можете запустить несколько параллелей GNU: 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 и даст 100 КБ строк для 48 sh с, работающих параллельно.

...