Параллелизация для цикла с очень большим количеством повторений

В моей системе у меня есть следующее в /var/lib/dpkg/info/netbase.postinst:

create_hosts_file() {
  if [ -e /etc/hosts ]; then return 0; fi

  cat > /etc/hosts <<-EOF
        127.0.0.1       localhost
        ::1             localhost ip6-localhost ip6-loopback
        fe00::0         ip6-localnet
        ff00::0         ip6-mcastprefix
        ff02::1         ip6-allnodes
        ff02::2         ip6-allrouters

EOF

Моя netbase версия 4.45.

Я ожидал бы, что имя на строке будет возвращено для обратного поиска IP-адреса, иначе я сомневаюсь относительно вопросов порядка.

3
28.09.2017, 12:57
4 ответа
  1. Вы не можете породить потоки от оболочки.
  2. Вы не хотите писать в тот же файл от нескольких процессов.
  3. Если все Ваш random программа делает, генерируют единственное число,
    • это должно быть достаточно быстро, что Ваш цикл будет связанным io.
    • если Вы можете, необходимо отредактировать его для взятия аргумента и печати что много чисел.
    • если фактическое выполнение является узким местом, необходимо заново обдумать, как генерировать числа. Возможно, отправьте код для Кодирования Обзора.

Если Вы действительно действительно все еще хотите сделать это этот путь, сделайте это в блоках:

for i in {0..9}; do
    for ((j = 1; j < $N/10; j++)); do
        ./random
    done > tmp$i &
    pid[$i]=$?
done
for i in {0..9}; do
    wait ${pid[$i]}
done
cat tmp{0..9} >> outfile
11
27.01.2020, 21:07

Я не знаю ни о какой оболочке, которая позволяет Вам вручную создавать новые потоки, обычно можно только использовать существующие потоки в текущей оболочке (или создать подоболочки, которые являются действительно новыми процессами). Использовать python или другой язык вместо этого.

Даже если бы Вы могли, я действительно не рекомендовал бы использовать сценарий оболочки для чего-то в этом масштабе. Потеря производительности по сравнению со скомпилированным языком при выполнении 10^6 повторения могла быть существенной.

4
27.01.2020, 21:07

Проблемой, как всегда, является конкуренция ресурса. Необходимо ограничить количество процессов/потоков, которые работают одновременно.

Кроме того, наличие параллельных потоков во многом зависит от того, какая обработка будет выполнена. Намного лучше, если существует хорошее соединение программирования: память, CPU, i/o, и т.д. Если все подпроцессы будут делать весь CPU, то наличие выполнения 10-20 сразу ничего не ускорит. Вы могли попытаться сдать обработку в аренду к другим машинам; например, использование ssh, чтобы запустить запросы к другим машинам и вернуть результаты.

Быстрая и грязная первичная обработка может быть чем-то как:

N=$1 # max number to iterate on
shift # rest of command line is the command to run: e.g. "./random"
maxcount=10 # maximum in the pool
curcount=0  # how many currently in the pool
reaper () {
    wait
    curcount=`expr $curcount - 1`
}
spawnnext () {
    n=$1
    shift
    while [ $curcount -ge $maxcount ]; do
        sleep 1 # wait for a free slot in the pool
    done
    echo $n
    "$@" &
    curcount=`expr $curcount + 1`
}

trap 'reaper' CHLD

for (( i=0; i < $N; i++)); do
    spawnnext $i "$@"
done

Примечание; Я не протестировал это; просто описал его на лету.

Но я сделал бы это в более высоком уровне, лучше работающий язык, такой как Python: https://stackoverflow.com/questions/3033952/python-thread-pool-similar-to-the-multiprocessing-pool

2
27.01.2020, 21:07

Если Ваша задача состоит в том, чтобы просто генерировать случайные числа:

perl -e 'for($t=0;$t<1000000;$t++) { print int(rand()*1000),"\n" }'

Если Ваша задача - действительно что-то еще, что можно использовать Параллель GNU:

parallel ./random :::: <(seq 1000000) > output

Можно установить Параллель GNU просто:

wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
chmod 755 parallel

Посмотрите вводные видео для узнавания больше: http://pi.dk/1

1
27.01.2020, 21:07

Теги

Похожие вопросы