如何有效地使用 GNU 并行

Den*_*nov 8 shell gnu-parallel

假设我想在压缩文本文件中找到所有匹配项:

$ gzcat file.txt.gz | pv --rate -i 5 | grep some-pattern
Run Code Online (Sandbox Code Playgroud)

pv --rate此处用于测量管道吞吐量。在我的机器上它大约是 420Mb/s(解压后)。

现在我正在尝试使用 GNU 并行执行并行 grep。

$ gzcat documents.json.gz | pv --rate -i 5 | parallel --pipe -j4 --round-robin grep some-pattern
Run Code Online (Sandbox Code Playgroud)

现在吞吐量下降到 ~260Mb/s。而更有趣的parallel过程本身是使用大量 CPU。多于grep进程(但少于gzcat)。

编辑 1:我尝试了不同的块大小 ( --block),以及-N/-L选项的不同值。在这一点上没有任何帮助。

我究竟做错了什么?

Ole*_*nge 9

我真的很惊讶你使用 GNU Parallel 的--pipe. 我的测试通常最大速度约为 100 MB/s。

您的瓶颈很可能在 GNU Parallel 中:--pipe效率不高。--pipepart然而,是:在这里我可以达到每个 CPU 核心 1 GB/s 的数量级。

不幸的是,使用有一些限制--pipepart

  • 该文件必须是可查找的(即没有管道)
  • 您必须能够使用 --recstart/--recend 找到记录的开头(即没有压缩文件)
  • 行号未知(因此您不能有 4 行记录)。

例子:

parallel --pipepart -a bigfile --block 100M grep somepattern
Run Code Online (Sandbox Code Playgroud)

  • 是的:GNU Parallel 是用 perl 编写的,并且使用 `--pipe` 每个字节都必须经过单个进程,它必须对每个字节进行一些处理。使用`--pipepart` 中央进程永远不会看到大多数字节:它们由生成的作业处理。由于几乎没有几行是 `--pipe` 中的瓶颈,我欢迎 C/C++ 编码员重写该部分,然后为在其路径中使用 C 编译器的人运行该部分。 (2认同)

und*_*ine 2

grep 非常有效 - 并行运行它是没有意义的。在你的命令中,只有解压需要更多的CPU,但这不能并行。

通过并行分割输入比通过 grep 获取匹配行需要更多的 cpu。

如果您希望使用每行需要更多 cpu 的东西而不是 grep ,那么情况会发生变化 - 那么并行会更有意义。

如果您希望加快此操作 - 看看瓶颈在哪里 - 可能是解压(然后帮助使用其他解压工具或更好的CPU)或 - 从磁盘读取(然后帮助使用其他解压工具或更好的磁盘系统)。

根据我的经验 - 有时最好使用 lzma(例如-2)来压缩/解压缩文件 - 它具有比 gzip 更高的压缩率,因此需要从磁盘读取的数据少得多,并且速度相当。