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

Я хочу распараллелить цикл for, где число итераций в цикле может быть очень большим, например 10 ^ 6. Таким образом, будет лучше, если я смогу создавать потоки, а не обрабатывать. Как это сделать? Код выглядит следующим образом

N=$1 for (( i=0; i < $N; i++ )); do ./random >> output /* in each iteration one random number is appended to a file "output" */ done 

4 Solutions collect form web for “Параллелизация цикла for с очень большим количеством итераций”

  1. Вы не можете создавать потоки из оболочки.
  2. Вы не хотите писать в один файл из нескольких процессов.
  3. Если вся ваша random программа генерирует один номер,
    • он должен быть достаточно быстрым, чтобы ваша петля была ограничена.
    • если можно, вы должны отредактировать его, чтобы принять аргумент и напечатать много чисел.
    • если фактическое выполнение является узким местом, вы должны переосмыслить, как сгенерировать числа. Возможно, разместите код в Code Review .

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

 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 - 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 

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

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

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

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

Быстрый и грязный первый проход может выглядеть примерно так:

 N=$1 # max number to iterate on shift # rest of command line is the command to run: eg "./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

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

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

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

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

Вы можете установить GNU Parallel, просто:

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

Смотрите видеоролики, чтобы узнать больше: http://pi.dk/1

  • сценарий оболочки, чтобы присоединиться к 2 файлам на основе 2 столбцов, и если совпадение найдено, напишите несколько полей
  • Проверяет наличие статуса выхода, отличного от 0, после команды `command || return` недостижимый?
  • Как добавить каждый элемент в список с помощью цикла?
  • Как работает опция -d для чтения bash?
  • Код возврата lftp
  • Скрипты на несколько серверов одновременно
  • Если «bash <file>» работает, почему «source <file>» выдает ошибку?
  • дисковое пространство отдельного пользователя
  • Как скрипт знает путь к файлу .desktop, который запустил его?
  • Превращение стандартного вывода в одну команду
  • использовать if else в Linux, чтобы определить, существует ли папка или нет.
  • Сценарий Bash для извлечения идентификатора сообщения и отправки силы
  • Interesting Posts

    Unix-эквивалент `du -sb` для получения суммарного размера в байтах

    Написание сценария, который показывает, сколько строк имеет «X» и «Y» в нем?

    Установите Lisp Interpreter в Debian Jessie

    Спящий режим запускается ровно через час

    bash не устанавливает autocd

    bash alias, начинающийся с pipe, не работает?

    Может ли что-нибудь полезное сделать с усеченным ядром?

    pssh (Parallel-ssh), передающий разные параметры для каждого хоста

    Дата эпохи GNU +% s по сравнению с фразами времени с расчетами, включая месяцы?

    Как увеличить масштаб отображения на дисплее?

    как получить процессор, которому в настоящее время назначен поток?

    Есть ли многопользовательский webdav-сервер для Linux?

    Как я могу использовать chroot в дистрибутиве Live filesystem.squashfs Linux?

    Создание точных немасштабированных буклетов с pdfbook автоматически

    Установите близость процесса из сценария оболочки, когда он запускается

    Linux и Unix - лучшая ОС в мире.