Параллелизация цикла 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

  • Накопить имя файла в файле журнала, используя сценарий оболочки
  • Как использовать sudo -i в сценарии оболочки
  • bash: невозможно установить переменную в сплошную строку
  • отправка нескольких вложений с помощью uuencode
  • Сравните несколько файлов с файлом ref и распечатайте, если это соответствует
  • Могу ли я помещать диапазоны в параметры?
  • Запустить сценарий оболочки из crontab после остановки / запуска / перезапуска сервера
  • Команда запуска / остановки в терминале без вмешательства человека?
  • Вложенный цикл while работает не так, как ожидалось
  • Если утверждение, дающее ответ «else» для обоих результатов cmp
  • BASH и поведение возврата каретки
  • Linux и Unix - лучшая ОС в мире.