Я пытался распараллелить следующий скрипт, в частности, каждый из трех экземпляров цикла FOR, используя GNU Parallel, но не смог. Четыре команды, содержащиеся в цикле FOR, выполняются последовательно, каждый цикл занимает около 10 минут.
#!/bin/bash
kar='KAR5'
runList='run2 run3 run4'
mkdir normFunc
for run in $runList
do
fsl5.0-flirt -in $kar"deformed.nii.gz" -ref normtemp.nii.gz -omat $run".norm1.mat" -bins 256 -cost corratio -searchrx -90 90 -searchry -90 90 -searchrz -90 90 -dof 12
fsl5.0-flirt -in $run".poststats.nii.gz" -ref $kar"deformed.nii.gz" -omat $run".norm2.mat" -bins 256 -cost corratio -searchrx -90 90 -searchry -90 90 -searchrz -90 90 -dof 12
fsl5.0-convert_xfm -concat $run".norm1.mat" -omat $run".norm.mat" $run".norm2.mat"
fsl5.0-flirt -in $run".poststats.nii.gz" -ref normtemp.nii.gz -out $PWD/normFunc/$run".norm.nii.gz" -applyxfm -init $run".norm.mat" -interp trilinear
rm -f *.mat
done
shell-script
gnu-parallel
Равнур С Джилл
источник
источник
wait
команду в конце, чтобы главный сценарий не завершился, пока не выполнятся все фоновые задания.nice
, но тогда я не знаю, закончится ли это когда-нибудь ..Образец задания
Последовательные пробеги
Параллельные трассы
Параллельные прогоны в партиях N-процесса
Также возможно использовать FIFO как семафоры и использовать их, чтобы гарантировать, что новые процессы будут порождены как можно скорее, и что одновременно будет запущено не более N процессов. Но это требует больше кода.
N процессов с семафором на основе FIFO:
источник
wait
ним в основном позволяет запускать все процессы, пока он не попадет вnth
процесс, а затем не дождется завершения всех остальных, верно?i
ноль, звоните, подождите. Инкрементi
после нулевого теста.wait
без аргументов ждет всех детей. Это делает его немного расточительным. Подход на основе конвейерного семафора дает вам более быстрый параллелизм (я уже использовал это в пользовательской системе-nt
-ot
mkfifo pipe-$$
команда нуждается в соответствующем праве записи в текущий каталог. Поэтому я предпочитаю указывать полный путь, так/tmp/pipe-$$
как он, скорее всего, имеет доступ на запись для текущего пользователя, а не полагается на текущий каталог. Да заменить все 3 вхожденияpipe-$$
.Работает ли это на самом деле, зависит от ваших команд; Я не знаком с ними.
rm *.mat
Выглядит немного склонный к конфликтам , если он работает параллельно ...источник
rm *.mat
на что-то подобное,rm $run".mat"
чтобы заставить его работать без вмешательства одного процесса в другой. Спасибо .wait
что я забыл.При этом будут использоваться семафоры, распараллеливающие столько итераций, сколько число доступных ядер (-j +0 означает, что вы будете распараллеливать N + 0 заданий , где N - количество доступных ядер ).
sem --wait сообщает, что нужно дождаться завершения всех итераций цикла for, прежде чем выполнять последовательные строки кода.
Примечание: вам потребуется «параллель» из параллельного проекта GNU (sudo apt-get install parallel).
источник
Один очень простой способ, которым я часто пользуюсь:
Это запустит команду, передавая в каждой строке файла «args» параллельно, запустив не более $ NUM_PARALLEL одновременно.
Вы также можете посмотреть опцию -I для xargs, если вам нужно заменить входные аргументы в разных местах.
источник
Кажется, что задания fsl зависят друг от друга, поэтому 4 задания не могут выполняться параллельно. Однако прогоны могут выполняться параллельно.
Создайте функцию bash за один запуск и запустите эту функцию параллельно:
Чтобы узнать больше, посмотрите вступительные видеоролики: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1 и проведите час, изучая учебное пособие http://www.gnu.org/software/parallel/parallel_tutorial.html Ваша команда линия будет любить тебя за это.
источник
export SHELL=/bin/bash
перед параллельной работой. В противном случае вы получите ошибку вроде:Unknown command 'myfunc arg'
Параллельное выполнение в максимальном одновременном N-процессе
источник
Мне очень нравится ответ от @lev, так как он очень просто позволяет контролировать максимальное количество процессов. Однако, как описано в руководстве , sem не работает с скобками.
Делает работу.
источник
В моем случае я не могу использовать семафор (я нахожусь в git-bash на Windows), поэтому я придумал общий способ разделения задачи между N работниками, прежде чем они начнутся.
Это хорошо работает, если задачи занимают примерно одинаковое количество времени. Недостатком является то, что, если одному из работников потребуется много времени, чтобы выполнить свою часть работы, остальные, которые уже закончили, не помогут.
Распределение работы среди N рабочих (1 на ядро)
источник
У меня были проблемы с
@PSkocik
русским решением. В моей системе нет пакета GNU Parallel, доступного в виде пакета, иsem
я создал исключение при сборке и запуске вручную. Затем я попробовал также пример семафора FIFO, который также породил некоторые другие ошибки, касающиеся связи.@eyeApps
предложил xargs, но я не знал, как заставить его работать с моим сложным вариантом использования (примеры будут приветствоваться).Вот мое решение для параллельных заданий, которые одновременно обрабатываются до
N
заданий, настроенных с помощью_jobs_set_max_parallel
:_lib_jobs.sh:
Пример использования:
источник