Sort --parallel 不是并行化

Jer*_*all 15 linux cpu sorting parallel-processing

我正在尝试使用带有 sort -u 的 egrep 从文件中提取一组唯一的行,然后计算它们。大约 10% 的行(字母表 [ATCG] 中的所有 100 个字符)是重复的。有两个文件,每个文件大约 3 个演出,50% 不相关,所以可能有 3 亿行。

LC_ALL=C  grep -E  <files> |  sort --parallel=24  -u | wc -m
Run Code Online (Sandbox Code Playgroud)

在 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
Run Code Online (Sandbox Code Playgroud)

我错过了什么?即使进程受 IO 限制,我也不应该看到并行处理吗?排序过程使用它在任何给定时间实际运行的处理器的 99%,所以如果它发生,我应该能够看到并行化。内存不是问题,我有 256 Gb 可以玩,其他任何东西都没有使用它。

我发现管道 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
Run Code Online (Sandbox Code Playgroud)

在进行这些基准测试时,很明显当管道输入排序根本没有并行化时。当允许读取文件时,排序会按照指示拆分负载。

pix*_*eat 30

sort 除非需要,否则不会创建线程,而对于小文件,它的开销太大。现在不幸的是 sort 将管道视为一个小文件。如果您想向 24 个线程提供足够的数据,那么您需要指定 sort 以使用大型内部缓冲区(当出现大文件时,sort 会自动执行此操作)。这是我们应该在上游改进的地方(至少在文档中)。所以你会想要这样的东西:

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

请注意,我已经为所有进程设置了 LC_ALL=C,因为它们都将从这些数据中受益)。

顺便说一句,您可以使用以下内容监视排序线程:

watch -n.1 ps -C sort -L -o pcpu
Run Code Online (Sandbox Code Playgroud)


Ole*_*nge 5

使用它,parsort您可以在多核计算机上更快地对大文件进行排序。

在 48 核机器上,您应该会看到排序速度提高了 3 倍。

parsort是 GNU Parallel 的一部分,应该是sort.