Sortuj - równoległe nie jest równoległe

10

Próbuję stworzyć unikalny zestaw linii wyciągniętych z pliku za pomocą egrep z sort -u, a następnie je policzyć. Około 10% linii (wszystkie 100 znaków z alfabetu [ATCG]) jest powielonych. Są dwa pliki, po około 3 koncerty, 50% nie ma znaczenia, więc może 300 milionów linii.

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

Pomiędzy LC_ALL = C a użyciem -x w celu przyspieszenia grep, najwolniejszą częścią jest jak dotąd sortowanie. Czytanie stron podręcznika doprowadziło mnie do --parallel = n, ale eksperymenty nie wykazały absolutnie żadnej poprawy. Trochę kopania u góry pokazało, że nawet przy --parallel = 24, proces sortowania działa zawsze tylko na jednym procesorze na raz.

Mam 4 układy z 6 rdzeniami i 2 wątkami / rdzeniem, co daje w sumie 48 procesorów logicznych. Zobacz lscpu, ponieważ / proc / cpuinfo byłby za długi.

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

czego mi brakuje? Nawet jeśli proces jest związany z IO, czy nie powinienem widzieć przetwarzania równoległego? Proces sortowania zużywa 99% procesora, na którym jest aktualnie włączony, więc powinienem być w stanie zobaczyć równoległość, jeśli tak się dzieje. Pamięć nie stanowi problemu, mam 256 Gb do zabawy i żadna z nich nie jest używana przez nic innego.

Coś, co odkryłem, przesyłając grep do pliku, a następnie czytając plik z sortowaniem:

 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

Wykonując te testy porównawcze, jest całkiem jasne, że kiedy dane wejściowe przesyłane potokowo wcale nie są równoległe. Po zezwoleniu na odczyt sortowanie plików dzieli ładunek zgodnie z instrukcją.

Jeremy Kemball
źródło
Co sortto za dystrybucja? Standard sortnie zna tej opcji.
ott--
uname -adaje „3.13.0-46-generic # 79-Ubuntu SMP” i lsb_release -atwierdzi, że nazwa kodowa 14.04.2 jest godna zaufania, oraz wersja, która jest częścią gnu coreutils, zgodnie z man sort.
Jeremy Kemball,
Wydaje mi się, że są tu fragmenty, które należy ponownie przeczytać: gnu.org/software/coreutils/manual/html_node/…
Hannu
Nie jestem pewien, czy rozumiem, co otrzymujesz w @Hannu, czy możesz być bardziej szczegółowy? sort --parallel = 2 również nie działa równolegle. Ani 4, ani 8. nproc zwraca 48 tak, jak powinno.
Jeremy Kemball,
1
Powiedziałbym ... nie używaj do tego coreutils. Zabawnie mieliśmy bardzo podobne pytanie i cóż ... każda inna metoda działa lepiej superuser.com/a/485987/10165
Journeyman Geek

Odpowiedzi:

24

sort nie tworzy wątku, chyba że jest to konieczne, a dla małych plików jest to po prostu zbyt duży narzut. Teraz niestety sortowanie traktuje potok jak mały plik. Jeśli chcesz podać wystarczającą ilość danych do 24 wątków, musisz określić sortowanie, aby użyć dużego bufora wewnętrznego (sortowanie robi to automatycznie, gdy prezentowane są duże pliki). Jest to coś, co powinniśmy ulepszyć na wyższym szczeblu (przynajmniej w dokumentacji). Więc będziesz chciał czegoś takiego:

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

Uwaga: Ustawiłem LC_ALL = C dla wszystkich procesów, ponieważ wszystkie one skorzystają z tych danych).

BTW możesz monitorować sortowanie wątków za pomocą czegoś takiego:

watch -n.1 ps -C sort -L -o pcpu
pixelbeat
źródło