Eu tenho um script python simples que lê stdin (uma única linha), faz algum processamento (análise de string, sem IO envolvido) e envia para stdout
e.g. python parse.py < in.txt > out.txt
Eu tenho um in.txt
tamanho de cerca de 200 GB e uso paralelo para acelerá-lo (tenho 8 núcleos de CPU).
cat in.txt | parallel -j8 -N1 --pipe python parse.py
O que observei na CPU é que eles não estão utilizando totalmente, por exemplo
%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
E
ps ax | grep python
Eu obtive
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 executo, ps ax | grep python
recebo arquivos temporários diferentes, presumo que a CPU seja desperdiçada ao lidar com esses arquivos temporários. Ou estou fazendo algo errado?
Responder1
Embora a resposta de Mark esteja correta e totalmente suportada, você pode querer experimentar um novo recurso.
cat file | parallel --pipe ...
atinge o máximo em cerca de 100 MB/s.
A nova opção experimental --pipepart oferece > 2 GB/s, mas requer que in.txt seja um arquivo real (procurável):
parallel -a in.txt --block 100M --pipepart python parse.py
Responder2
Isso -N1
está fazendo com que um processo seja criado por linha. Você está vendo a sobrecarga da configuração paralela. Você deve alterar o script python para lidar com mais de uma linha. Então cat in.txt | parallel --pipe python parse.py
deve fazer uso total das CPUs.