===== Lanzar procesos en paralelo fácilmente con xargs =====
La paralelización de procesos entre múltiples núcleos o procesadores (SMT / CMT / SMP / HT / ...) se puede realizar de dos formas. La primera es por medio de la aplicación en si al estar programada para utilizar hilos (multithreading) o librerías como TBB (Threading Building Blocks) de Intel. Otra manera es utilizar varias copias de la aplicación, pero de forma que cada copia procese un trozo de datos definido. En este caso el sistema operativo asignará procesos entre núcleos o procesadores (multitarea) de forma automática.
Con el comando xarg y su opción //-P// podemos utilizar la paralelización de procesos que no fueron programados para funcionar en paralelo. Veremos algunos ejemplos de uso y los beneficios en tiempos de procesamiento con el comando time.
--max-procs=max-procs
-P max-procs
Run up to max-procs processes at a time; the default is 1. If max-procs is 0, xargs will run as many processes as possible at a time. Use the -n option with -P; otherwise chances are that only one exec will be done.
**Sin paralelización**: Listamos los ficheros de un directorio y se realiza la suma md5 de cada uno de ellos.
time ls * | xargs -I ARG -P1 -n1 md5sum ARG
real 0m3.401s
user 0m2.637s
sys 0m0.177s
**Sin paralelización**: Se realiza la suma md5 de cada fichero del directorio actual. Lo mismo que el anterior pero sin tubería.
time md5sum *
real 0m2.807s
user 0m2.640s
sys 0m0.170s
**Paralelizar md5sum**: Se crean 8 procesos md5sum que son ejecutados a la vez (paralelización).
time ls * | xargs -I ARG -P8 -n1 md5sum ARG
real 0m1.412s
user 0m2.723s
sys 0m0.230s
Ver en qué núcleo se ejecutan los procesos paralelizados.
ps -eF | grep -i md5sum
busi 12153 12151 0 3540 1404 3 16:59 pts/0 00:00:00 md5sum fichero1
busi 12154 12151 0 3540 1296 1 16:59 pts/0 00:00:00 md5sum fichero2
busi 12155 12151 0 3540 1312 1 16:59 pts/0 00:00:00 md5sum fichero3
busi 12156 12151 0 3540 1476 6 16:59 pts/0 00:00:00 md5sum fichero4
busi 12157 12151 0 3540 1360 1 16:59 pts/0 00:00:00 md5sum fichero5
busi 12158 12151 0 3540 1336 3 16:59 pts/0 00:00:00 md5sum fichero6
busi 12160 12151 0 3540 1360 2 16:59 pts/0 00:00:00 md5sum fichero7
busi 12161 12151 0 3540 1308 6 16:59 pts/0 00:00:00 md5sum fichero8
**Núcleos en uso según el comando ps** (Séptima columna): 1,2,3,6
==== ¿Es posible paralelizar procesos en Bash / Shellscripts? ====
No, no hay métodos nativos de paralelización de procesos en bash / shellscripts. La única posibilidad que podría tener un resultado similar, es utilizar procesos en segundo plano, en conjunción con las utilidades //taskset// y //wait//. De esta manera se puede asignar determinados núcleos a cada proceso y dejar el script en espera hasta que los procesos en background terminen.
Para reservar núcleos a determinados procesos de forma exclusiva se puede utilizar la directiva "//isolcpus//" en el cargador de arranque GRUB, de esta manera se consigue que tras el inicio, el kernel no asigne procesos a dicho/s núcleo/s y podamos hacerlo posteriormente nosotros con la utilidad taskset.