J'ai essayé de paralléliser le script suivant, en particulier chacune des trois instances de boucle FOR, en utilisant GNU Parallel mais je n'ai pas pu le faire. Les 4 commandes contenues dans la boucle FOR sont exécutées en série, chaque boucle prenant environ 10 minutes.
#!/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
Ravnoor S Gill
la source
la source
wait
commande à la fin pour que le script maître ne se ferme pas tant que tous les travaux en arrière-plan ne sont pas terminés.nice
, mais alors je ne sais pas si cela finirait jamais ..Exemple de tâche
Pistes séquentielles
Courses parallèles
Les exécutions parallèles dans des lots de N-processus
Il est également possible d'utiliser des FIFO comme sémaphores et de les utiliser pour s'assurer que les nouveaux processus sont générés le plus rapidement possible et que pas plus de N processus ne s'exécutent en même temps. Mais cela nécessite plus de code.
N processus avec un sémaphore basé sur FIFO:
la source
wait
qui la contient permet en principe que tous les processus s’exécutent, jusqu’à ce qu’ils atteignent lenth
processus, puis attend que tous les autres s’achèvent, est-ce exact?i
est égal à zéro, appelez attendre. Incrémenti
après le test zéro.wait
w / no arg attend tous les enfants. Cela fait un peu de gaspillage. L'approche basée sur les sémaphores de pipe vous donne une concurrence plus fluide (je l'utilise dans un système de construction basé sur un shell personnalisé avec-nt
/-ot
checks avec succès depuis un moment maintenant)mkfifo pipe-$$
commande nécessite un accès en écriture approprié au répertoire actuel. Donc, je préfère spécifier le chemin complet tel/tmp/pipe-$$
qu'il a très probablement un accès en écriture disponible pour l'utilisateur actuel plutôt que de compter sur le répertoire actuel. Oui, remplacez les 3 occurrences depipe-$$
.Que cela fonctionne réellement dépend de vos commandes; Je ne les connais pas. Le
rm *.mat
semble un peu sujet aux conflits si elle s'exécute en parallèle ...la source
rm *.mat
à quelque chose commerm $run".mat"
pour le faire fonctionner sans que l'un des processus interfère avec l'autre. Je vous remercie .wait
, que j'ai oublié.Cela utilisera des sémaphores, en parallélisant autant d'itérations que le nombre de cœurs disponibles (-j +0 signifie que vous allez paralléliser N + 0 travaux , N étant le nombre de cœurs disponibles ).
sem --wait indique d'attendre la fin de l'exécution de toutes les itérations de la boucle for avant d'exécuter les lignes de code successives.
Note: vous aurez besoin du "parallèle" du projet parallèle GNU (sudo apt-get install parallel).
la source
Un moyen très simple que j'utilise souvent:
Cela exécutera la commande, en passant chaque ligne du fichier "args" en parallèle, en exécutant au plus $ NUM_PARALLEL en même temps.
Vous pouvez également examiner l'option -I pour xargs si vous devez substituer les arguments d'entrée à différents endroits.
la source
Il semble que les travaux fsl dépendent les uns des autres, de sorte que les 4 travaux ne peuvent pas être exécutés en parallèle. Les pistes, cependant, peuvent être exécutées en parallèle.
Créez une fonction bash exécutant une seule exécution et exécutez-la en parallèle:
Pour en savoir plus, regardez les vidéos d'introduction: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1 et passez une heure à parcourir le didacticiel http://www.gnu.org/software/parallel/parallel_tutorial.html Votre commande La ligne vous aimera pour cela.
la source
export SHELL=/bin/bash
avant d'exécuter en parallèle. Sinon, vous obtiendrez une erreur du type:Unknown command 'myfunc arg'
Exécution parallèle dans le nombre maximum de processus simultanés
la source
J'aime beaucoup la réponse de @lev car elle permet de contrôler très simplement le maximum de processus. Cependant, comme décrit dans le manuel , sem ne fonctionne pas avec des crochets.
Fait le travail.
la source
Dans mon cas, je ne peux pas utiliser le sémaphore (je suis dans git-bash sous Windows), alors je suis arrivé avec un moyen générique de diviser la tâche entre N travailleurs, avant qu'ils ne commencent.
Cela fonctionne bien si les tâches prennent à peu près le même temps. L'inconvénient est que, si l'un des travailleurs met longtemps à faire son travail, les autres qui ont déjà terminé ne l'aideront pas.
Division du travail entre N travailleurs (1 par noyau)
la source
J'ai eu du mal avec
@PSkocik
la solution de. GNU Parallel n’est pas disponible dans mon système en tant que package et asem
généré une exception lorsque je l’ai construit et exécuté manuellement. J'ai ensuite essayé l'exemple du sémaphore FIFO, qui a également généré d'autres erreurs en matière de communication.@eyeApps
xargs suggéré mais je ne savais pas comment le faire fonctionner avec mon cas d'utilisation complexe (des exemples seraient les bienvenus).Voici ma solution pour les travaux parallèles qui traitent jusqu'à des
N
travaux à la fois, comme configuré par_jobs_set_max_parallel
:_lib_jobs.sh:
Exemple d'utilisation:
la source