정렬-병렬이 병렬화되지 않습니다

sort -u를 사용하여 egrep을 사용하여 파일에서 가져온 일련의 행을 고유하게 만들고 계산합니다. 선의 약 10 % (알파벳 [ATCG]에서 100 자 길이)가 복제됩니다. 각각 약 3 기가있는 두 개의 파일이 있으며 50 %는 관련이 없으므로 아마도 3 억 줄입니다.

LC_ALL=C  grep -E  <files> |  sort --parallel=24  -u | wc -m

LC_ALL = C와 -x를 사용하여 grep을 가속화 할 때 가장 느린 부분이 정렬입니다. 매뉴얼 페이지를 읽으면 –parallel = n이되었지만 실험은 전혀 개선되지 않았습니다. top으로 약간 파고 들자 –parallel = 24를 사용하더라도 정렬 프로세스는 한 번에 하나의 프로세서에서만 실행됩니다.

6 개의 코어와 2 개의 스레드 / 코어를 가진 4 개의 칩이 있으며 총 48 개의 논리 프로세서를 제공합니다. / proc / cpuinfo가 너무 길기 때문에 lscpu를 참조하십시오.

Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                48
On-line CPU(s) list:   0-47
Thread(s) per core:    2
Core(s) per socket:    6
Socket(s):             4
NUMA node(s):          8
Vendor ID:             AuthenticAMD
CPU family:            21
Model:                 1
Stepping:              2
CPU MHz:               1400.000
BogoMIPS:              5199.96

내가 무엇을 놓치고 있습니까? 프로세스가 IO 바운드 인 경우에도 병렬 처리가 표시되지 않아야합니까? 정렬 프로세스는 주어진 시간에 실제로있는 프로세서의 99 %를 사용하므로 병렬화가 발생하면 볼 수 있습니다. 메모리는 문제가되지 않습니다 .256Gb를 가지고 있으며 다른 어떤 것도 사용하지 않습니다.

grep을 파일에 파이핑 한 다음 정렬로 파일을 읽는 것을 발견했습니다.

 LC_ALL=C  grep -E  <files>  > reads.txt ; sort reads.txt  -u | wc -m

default, file 1m 50s
--parallel=24, file 1m15s
--parallel=48, file 1m6s
--parallel=1, no file 10m53s
--parallel=2, no file 10m42s
--parallel=4 no file 10m56s

others still running

이러한 벤치 마크를 수행 할 때 파이프 입력 정렬이 전혀 병렬화되지 않는 것이 분명합니다. 파일 정렬을 읽을 수 있으면 지시에 따라로드가 분할됩니다.



답변

sort는 필요하지 않으면 스레드를 만들지 않으며 작은 파일의 경우 오버 헤드가 너무 많습니다. 불행히도 sort는 파이프를 작은 파일처럼 취급합니다. 24 개의 스레드에 충분한 데이터를 공급하려면 큰 내부 버퍼를 사용하도록 정렬하도록 지정해야합니다 (큰 파일이 표시 될 때 자동으로 정렬합니다). 이것은 업스트림에서 개선해야하는 것입니다 (적어도 문서화에서는). 따라서 다음과 같은 것을 원할 것입니다.

(export LC_ALL=C; grep -E  <files> | sort -S1G --parallel=24 -u | wc -m)

참고 모든 프로세스에 대해 LC_ALL = C를 설정했습니다. 모두이 데이터를 활용할 수 있기 때문입니다).

BTW는 다음과 같이 정렬 스레드를 모니터링 할 수 있습니다.

watch -n.1 ps -C sort -L -o pcpu


답변