Ich habe versucht, das folgende Skript, insbesondere jede der drei FOR-Schleifeninstanzen, mit GNU Parallel zu parallelisieren, konnte dies jedoch nicht. Die 4 in der FOR-Schleife enthaltenen Befehle werden nacheinander ausgeführt, wobei jede Schleife etwa 10 Minuten dauert.
#!/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
quelle
quelle
wait
am Ende einen Befehl hinzufügen, damit das Masterskript erst beendet wird, wenn alle Hintergrundjobs beendet sind.nice
, aber dann weiß ich nicht, ob es jemals zu EndeBeispielaufgabe
Sequentielle Läufe
Parallele Läufe
Parallele Läufe in N-Prozess-Chargen
Es ist auch möglich, FIFOs als Semaphore zu verwenden, um sicherzustellen, dass neue Prozesse so schnell wie möglich erstellt werden und nicht mehr als N Prozesse gleichzeitig ausgeführt werden. Dafür ist jedoch mehr Code erforderlich.
N Prozesse mit einem FIFO-basierten Semaphor:
quelle
wait
darin lässt im Grunde alle Prozesse laufen, bis sie dennth
Prozess erreicht, und wartet dann , bis alle anderen beendet sind. Stimmt das?i
Null ist, rufen Sie Wait an. Inkrementi
nach dem Nulltest.wait
w / no arg wartet auf alle Kinder. Das macht es ein wenig verschwenderisch. Der Pipe-basierte Semaphor-Ansatz bietet eine flüssigere Parallelität (ich verwende dies in einem benutzerdefinierten Shell-basierten Build-System zusammen mit-nt
/-ot
checks bereits seitmkfifo pipe-$$
Befehl benötigt einen entsprechenden Schreibzugriff auf das aktuelle Verzeichnis. Daher ziehe ich es vor, den vollständigen Pfad anzugeben, da/tmp/pipe-$$
der aktuelle Benutzer höchstwahrscheinlich über Schreibzugriff verfügt, anstatt sich auf das aktuelle Verzeichnis zu verlassen. Ja, alle 3 Vorkommen von ersetzenpipe-$$
.Ob es tatsächlich funktioniert, hängt von Ihren Befehlen ab. Ich kenne sie nicht. Das
rm *.mat
sieht etwas konfliktanfällig aus, wenn es parallel läuft ...quelle
rm *.mat
etwas ändern ,rm $run".mat"
um es zum Laufen zu bringen, ohne dass ein Prozess den anderen stört. Vielen Dank .wait
die ich vergessen habe.Hierbei werden Semaphore verwendet, die so viele Iterationen parallelisieren, wie Kerne verfügbar sind (-j +0 bedeutet, dass Sie N + 0 Jobs parallelisieren , wobei N die Anzahl der verfügbaren Kerne ist ).
sem --wait weist an, zu warten, bis alle Iterationen in der for-Schleife die Ausführung beendet haben, bevor die aufeinanderfolgenden Codezeilen ausgeführt werden.
Hinweis: Sie benötigen "parallel" aus dem GNU-Parallel-Projekt (sudo apt-get install parallel).
quelle
Eine wirklich einfache Möglichkeit, die ich oft benutze:
Dadurch wird der Befehl ausgeführt, wobei in jeder Zeile der "args" -Datei gleichzeitig höchstens $ NUM_PARALLEL ausgeführt wird.
Sie können auch die Option -I für xargs prüfen, wenn Sie die Eingabeargumente an verschiedenen Stellen ersetzen müssen.
quelle
Es scheint, dass die fsl-Jobs voneinander abhängig sind, sodass die 4 Jobs nicht gleichzeitig ausgeführt werden können. Die Läufe können jedoch parallel ausgeführt werden.
Erstellen Sie eine Bash-Funktion, die einen einzelnen Lauf ausführt, und führen Sie diese Funktion parallel aus:
Weitere Informationen finden Sie in den Introvideos: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1. Gehen Sie eine Stunde lang durch das Tutorial http://www.gnu.org/software/parallel/parallel_tutorial.html Ihr Befehl line wird dich dafür lieben.
quelle
export SHELL=/bin/bash
bevor Sie sie parallel ausführen können. Andernfalls erhalten Sie eine Fehlermeldung wie:Unknown command 'myfunc arg'
Parallele Ausführung im max. N-Prozess gleichzeitig
quelle
Die Antwort von @lev gefällt mir sehr gut, da sie auf sehr einfache Weise die Kontrolle über die maximale Anzahl von Prozessen ermöglicht. Wie im Handbuch beschrieben , funktioniert sem jedoch nicht mit Klammern.
Macht den Job.
quelle
In meinem Fall kann ich kein Semaphor verwenden (ich bin in Git-Bash unter Windows), daher habe ich eine generische Methode gefunden, um die Aufgabe auf N Worker aufzuteilen, bevor sie beginnen.
Es funktioniert gut, wenn die Aufgaben ungefähr die gleiche Zeit in Anspruch nehmen. Der Nachteil ist, dass die anderen, die bereits fertig sind, nicht helfen, wenn einer der Arbeiter viel Zeit benötigt, um seinen Teil der Arbeit zu erledigen.
Aufteilung des Jobs auf N Arbeiter (1 pro Kern)
quelle
Ich hatte Probleme mit
@PSkocik
der Lösung. Mein System verfügt nicht über GNU Parallel als Paket und hatsem
eine Ausnahme ausgelöst, als ich es manuell erstellt und ausgeführt habe. Ich habe dann auch das FIFO-Semaphor-Beispiel ausprobiert, das auch einige andere Kommunikationsfehler aufwies.@eyeApps
schlug xargs vor, aber ich wusste nicht, wie ich es mit meinem komplexen Anwendungsfall zum Laufen bringen sollte (Beispiele wären willkommen).Hier ist meine Lösung für parallele Jobs, die bis zu
N
Jobs gleichzeitig verarbeiten, wie konfiguriert von_jobs_set_max_parallel
:_lib_jobs.sh:
Anwendungsbeispiel:
quelle