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

3325
Jeremy Kemball

Я пытаюсь сделать уникальный набор строк, извлеченных из файла с помощью 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 

При выполнении этих тестов довольно ясно, что когда сортировка ввода по каналу вообще не распараллеливается. Когда разрешено читать файлы, сортировка распределяет нагрузку в соответствии с инструкциями.

8
Что это за сортировка? Стандартный `sort` не знает эту опцию. ott-- 9 лет назад 0
`uname -a` выдает" 3.13.0-46-generic # 79-Ubuntu SMP ", а` lsb_release -a` утверждает, что верное кодовое имя 14.04.2, и версию sort, которая входит в состав gnu coreutils, согласно `man sort `. Jeremy Kemball 9 лет назад 0
Мне кажется, здесь есть разделы, которые необходимо перечитать: https://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html. Hannu 9 лет назад 0
Я не уверен, что понимаю, что вы получаете на @Hannu, не могли бы вы быть более конкретным? sort --parallel = 2 также не распараллеливает. Ни 4, ни 8. Также nproc не возвращает 48, как должно. Jeremy Kemball 9 лет назад 0
Я бы сказал ... не используйте coreutils для этого. * Забавно * у нас был очень похожий вопрос и хорошо .... любой другой метод работает лучше http://superuser.com/a/485987/10165 Journeyman Geek 9 лет назад 1
@JeremyKemball - тот факт, что n> 8 мало что добавит для начинающих, мне также показалось, что использование -u (уникального) не соответствует тому, что вы просили; лучше использовать `unique`, а не` sort -u` Hannu 9 лет назад 0
сортировать | uniq` и and `sort -u` явно эквивалентны, если вы не используете ключи для сортировки строк. Есть ли причина использовать дополнительную трубу? Jeremy Kemball 9 лет назад 0
От того, как я понимаю текст по ссылке выше, есть разница. Но тогда я НЕ носитель английского языка. Hannu 9 лет назад 0
Они отличаются в крайнем случае сравнением, если вы указали параметры упорядочения / сортировки, так что вещи, которые сортируют одинаково, уникальны по этим параметрам сортировки. У меня нет -d, -f, -n, -h, -M, -v или -k, поэтому `sort | uniq` явно идентичен `sort --unique`, вдвойне, так как у меня очень скучные строки. Jeremy Kemball 9 лет назад 0

1 ответ на вопрос

18
pixelbeat

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

Похожие вопросы