Gnu paralelo no utiliza toda la CPU

Gnu paralelo no utiliza toda la CPU

Tengo un script de Python simple que lee desde stdin (una sola línea), realiza algún procesamiento (análisis de cadenas, sin IO involucrado) y lo envía a stdout

e.g. python parse.py < in.txt > out.txt

Tengo un in.txttamaño de alrededor de 200 GB y uso paralelo para acelerarlo (tengo 8 núcleos de CPU).

cat in.txt | parallel -j8 -N1 --pipe python parse.py

Lo que observé que la CPU no se está utilizando por completo, por ejemplo

%Cpu0  :  9.1 us, 22.7 sy,  0.0 ni, 68.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu1  : 27.3 us, 13.6 sy,  0.0 ni, 59.1 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu2  : 14.3 us, 71.4 sy,  0.0 ni, 14.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu3  : 14.3 us, 28.6 sy,  0.0 ni, 57.1 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu4  : 14.3 us, 38.1 sy,  0.0 ni, 47.6 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu5  :  4.8 us, 23.8 sy,  0.0 ni, 71.4 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu6  : 15.0 us, 20.0 sy,  0.0 ni, 65.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu7  : 23.8 us, 19.0 sy,  0.0 ni, 57.1 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st

Y

ps ax | grep python

Obtuve

12450 ?        S      0:00 /bin/bash -c               sh -c 'dd bs=1 count=1 of=/tmp/2NQLo8j4qy.chr 2>/dev/null';              test ! -s "/tmp/2NQLo8j4qy.chr" && rm -f "/tmp/2NQLo8j4qy.chr" && exec true;              (cat /tmp/2NQLo8j4qy.chr; rm /tmp/2NQLo8j4qy.chr; cat - ) | (python parse.py);
12453 ?        S      0:00 /bin/bash -c               sh -c 'dd bs=1 count=1 of=/tmp/zYnfr4Ss8H.chr 2>/dev/null';              test ! -s "/tmp/zYnfr4Ss8H.chr" && rm -f "/tmp/zYnfr4Ss8H.chr" && exec true;              (cat /tmp/zYnfr4Ss8H.chr; rm /tmp/zYnfr4Ss8H.chr; cat - ) | (python parse.py);
12456 ?        S      0:00 /bin/bash -c               sh -c 'dd bs=1 count=1 of=/tmp/wlrI14juYz.chr 2>/dev/null';              test ! -s "/tmp/wlrI14juYz.chr" && rm -f "/tmp/wlrI14juYz.chr" && exec true;              (cat /tmp/wlrI14juYz.chr; rm /tmp/wlrI14juYz.chr; cat - ) | (python parse.py);
12459 ?        S      0:00 /bin/bash -c               sh -c 'dd bs=1 count=1 of=/tmp/cyArLNBTTm.chr 2>/dev/null';              test ! -s "/tmp/cyArLNBTTm.chr" && rm -f "/tmp/cyArLNBTTm.chr" && exec true;              (cat /tmp/cyArLNBTTm.chr; rm /tmp/cyArLNBTTm.chr; cat - ) | (python parse.py);
12461 pts/0    S+     0:00 grep --color=auto python
15211 ?        S    144:22 perl /usr/bin/parallel -j8 -N1 --pipe python parse.py

Cada vez que ejecuto ps ax | grep pythonobtengo diferentes archivos temporales, ¿supongo que se desperdicia CPU al tratar con estos archivos temporales? ¿O estoy haciendo algo mal?

Respuesta1

Si bien la respuesta de Mark es correcta y totalmente compatible, es posible que desee probar una nueva función.

cat file | parallel --pipe ...

alcanza un máximo de alrededor de 100 MB/s.

La nueva opción experimental --pipepart ofrece > 2 GB/s, pero requiere que in.txt sea un archivo real (buscable):

parallel -a in.txt --block 100M --pipepart python parse.py

Respuesta2

Esto -N1está provocando que se cree un proceso por línea. Estás viendo la sobrecarga de la configuración paralela. Debe modificar la secuencia de comandos de Python para manejar más de una línea. Entonces cat in.txt | parallel --pipe python parse.pydebería hacer un uso completo de las CPU.

información relacionada