모든 CPU를 활용하지 않는 Gnu 병렬

모든 CPU를 활용하지 않는 Gnu 병렬

stdin(한 줄)에서 읽고 일부 처리(문자열 구문 분석, IO 관련 없음)를 수행하고 stdout으로 출력하는 간단한 Python 스크립트가 있습니다.

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

나는 in.txt크기가 약 200GB이고 속도를 높이기 위해 병렬을 사용합니다(CPU 코어는 8개입니다).

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

내가 관찰한 바에 따르면 CPU는 완전히 활용되지 않고 있습니다.

%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

그리고

ps ax | grep python

나는 얻었다

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

실행할 때마다 ps ax | grep python다른 임시 파일이 생성됩니다. 이러한 임시 파일을 처리하는 데 CPU가 낭비된다고 가정합니까? 아니면 내가 뭔가 잘못하고 있는 걸까요?

답변1

Mark의 답변은 정확하고 완벽하게 지원되지만 새로운 기능을 사용해 보고 싶을 수도 있습니다.

cat file | parallel --pipe ...

최대 속도는 약 100MB/s입니다.

새로운 실험적 옵션 --pipepart는 > 2GB/s를 제공하지만 in.txt가 실제(검색 가능한) 파일이어야 합니다.

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

답변2

이로 -N1인해 한 줄에 하나의 프로세스가 생성됩니다. 병렬 설정의 오버헤드가 표시됩니다. 두 개 이상의 라인을 처리하려면 Python 스크립트를 변경해야 합니다. 그런 다음 cat in.txt | parallel --pipe python parse.pyCPU를 최대한 활용해야 합니다.

관련 정보