Сортировка - параллель не распараллеливает

10

Я пытаюсь сделать уникальный набор строк, извлеченных из файла с помощью egrep с помощью sort -u, а затем сосчитать их. Около 10% строк (все 100 символов из алфавита [ATCG]) дублируются. Есть два файла, около 3 гигабайт каждый, 50% не имеют отношения, поэтому, возможно, 300 миллионов строк.

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

Между LC_ALL = C и использованием -x для ускорения grep самая медленная часть на данный момент является сортировкой. Чтение справочных страниц привело меня к --parallel = n, но эксперименты не показали абсолютно никаких улучшений. Небольшое копание с top показало, что даже при --parallel = 24 процесс сортировки всегда выполняется только на одном процессоре за раз.

У меня 4 чипа с 6 ядрами и 2 потоками на ядро, что дает в общей сложности 48 логических процессоров. Смотрите lscpu, потому что / proc / cpuinfo будет слишком длинным.

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% процессора, на котором он фактически работает в любой момент времени, поэтому я должен видеть распараллеливание, если это происходит. Память не имеет значения, у меня есть 256 Гб для игры, и ничто из этого не используется.

Что-то, что я обнаружил, отправляя grep в файл, затем читая файл с помощью команды sort:

 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не знает эту опцию.
ot--
uname -aвыдает "3.13.0-46-generic # 79-Ubuntu SMP" и lsb_release -aутверждает, что кодовое имя 14.04.2 надежное, и версию sort, которая является частью gnu coreutils, согласно man sort.
Джереми Кембалл
Мне кажется, что здесь есть части, которые необходимо перечитать: gnu.org/software/coreutils/manual/html_node/…
Hannu
Я не уверен, что понимаю, что вы получаете на @Hannu, не могли бы вы быть более конкретным? sort --parallel = 2 также не распараллеливает. Ни 4, ни 8 не делают. Nproc возвращает 48, как должно.
Джереми Кембалл
1
Я бы сказал ... не используйте coreutils для этого. Занятно мы имели очень похожий вопрос и хорошо .... каждый метод работает лучше superuser.com/a/485987/10165
подмастерье - мастер

Ответы:

24

Сортировка не создает поток, если в этом нет необходимости, а для маленьких файлов это слишком много. К сожалению, сортировка обрабатывает трубу как маленький файл. Если вы хотите подать достаточное количество данных в 24 потока, вам необходимо указать сортировку для использования большого внутреннего буфера (сортировка делает это автоматически при представлении больших файлов). Это то, что мы должны улучшить в апстриме (по крайней мере, в документации). Итак, вы хотите что-то вроде:

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

Обратите внимание, что я установил LC_ALL = C для всех процессов, так как все они получат выгоду от этих данных).

Кстати, вы можете отслеживать темы сортировки с помощью чего-то вроде:

watch -n.1 ps -C sort -L -o pcpu
pixelbeat
источник