He estado tratando de paralelizar el siguiente script, específicamente cada una de las tres instancias de bucle FOR, usando GNU Parallel, pero no he podido. Los 4 comandos contenidos dentro del ciclo FOR se ejecutan en serie, cada ciclo toma alrededor de 10 minutos.
#!/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
fuente
fuente
wait
comando al final para que el script maestro no salga hasta que lo hagan todos los trabajos en segundo plano.nice
, pero entonces no sé si alguna vez terminaría ...Tarea de muestra
Carreras secuenciales
Carreras paralelas
Ejecuciones paralelas en lotes de proceso N
También es posible usar FIFOs como semáforos y usarlos para garantizar que se generen nuevos procesos lo antes posible y que no se ejecuten más de N procesos al mismo tiempo. Pero requiere más código.
N procesos con un semáforo basado en FIFO:
fuente
wait
que contiene básicamente permite que todos los procesos se ejecuten, hasta que llegue alnth
proceso, luego espera a que todos los demás terminen de ejecutarse, ¿no es así?i
es cero, llame a wait. Incrementoi
después de la prueba cero.wait
w / no arg espera a todos los niños. Eso lo hace un poco despilfarrador. El enfoque de semáforo basado en tubería le brinda una concurrencia más fluida (lo he estado usando en un sistema de construcción basado en shell personalizado junto con-nt
/-ot
comprobaciones con éxito durante un tiempo ahora)mkfifo pipe-$$
comando necesita acceso de escritura adecuado al directorio actual. Por lo tanto, prefiero especificar la ruta completa, ya/tmp/pipe-$$
que lo más probable es que tenga acceso de escritura disponible para el usuario actual en lugar de depender del directorio actual. Sí, reemplace las 3 ocurrencias depipe-$$
.Si realmente funciona depende de sus comandos; No estoy familiarizado con ellos. El
rm *.mat
parece un poco propenso a conflictos si se ejecuta en paralelo ...fuente
rm *.mat
a algo comorm $run".mat"
hacer que funcione sin que un proceso interfiera con el otro. Gracias .wait
, que olvidé.Esto usará semáforos, paralelizando tantas iteraciones como el número de núcleos disponibles (-j +0 significa que paralelizará N + 0 trabajos , donde N es el número de núcleos disponibles ).
sem --wait le dice que espere hasta que todas las iteraciones en el ciclo for hayan terminado la ejecución antes de ejecutar las líneas de código sucesivas.
Nota: necesitará "paralelo" del proyecto paralelo GNU (sudo apt-get install parallel).
fuente
Una forma realmente fácil que uso a menudo:
Esto ejecutará el comando, pasando cada línea del archivo "args", en paralelo, ejecutando como máximo $ NUM_PARALLEL al mismo tiempo.
También puede buscar en la opción -I para xargs, si necesita sustituir los argumentos de entrada en diferentes lugares.
fuente
Parece que los trabajos fsl dependen unos de otros, por lo que los 4 trabajos no se pueden ejecutar en paralelo. Las ejecuciones, sin embargo, pueden ejecutarse en paralelo.
Haga una función bash ejecutando una sola ejecución y ejecute esa función en paralelo:
Para obtener más información, vea los videos de introducción: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1 y pase una hora caminando a través del tutorial http://www.gnu.org/software/parallel/parallel_tutorial.html Su comando Line te amará por eso.
fuente
export SHELL=/bin/bash
antes de ejecutarlo en paralelo. De lo contrario, obtendrá un error como:Unknown command 'myfunc arg'
Ejecución paralela en proceso N máximo concurrente
fuente
Realmente me gusta la respuesta de @lev, ya que proporciona control sobre el número máximo de procesos de una manera muy simple. Sin embargo, como se describe en el manual , sem no funciona con corchetes.
Hace el trabajo.
fuente
En mi caso, no puedo usar el semáforo (estoy en git-bash en Windows), así que se me ocurrió una forma genérica de dividir la tarea entre los trabajadores de N, antes de que comiencen.
Funciona bien si las tareas toman aproximadamente la misma cantidad de tiempo. La desventaja es que, si uno de los trabajadores toma mucho tiempo para hacer su parte del trabajo, los otros que ya terminaron no ayudarán.
División del trabajo entre N trabajadores (1 por núcleo)
fuente
Tuve problemas con
@PSkocik
la solución. Mi sistema no tiene GNU Parallel disponible como paquete ysem
arrojó una excepción cuando lo construí y lo ejecuté manualmente. Luego probé el ejemplo del semáforo FIFO, que también arrojó algunos otros errores con respecto a la comunicación.@eyeApps
sugerí xargs pero no sabía cómo hacerlo funcionar con mi caso de uso complejo (los ejemplos serían bienvenidos).Aquí está mi solución para trabajos paralelos que procesan hasta
N
trabajos a la vez según lo configurado por_jobs_set_max_parallel
:_lib_jobs.sh:
Ejemplo de uso:
fuente