如何有效地使用 GNU 并行

如何有效地使用 GNU 并行

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

$ gzcat file.txt.gz | pv --rate -i 5 | grep some-pattern

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

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

$ gzcat documents.json.gz | pv --rate -i 5 | parallel --pipe -j4 --round-robin grep some-pattern

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

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

我究竟做错了什么?

答案1

我真的很惊讶你使用 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

答案2

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

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

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

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

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

答案3

减压是这里的瓶颈。如果解压内部没有并行化,你自己是无法实现的。如果您有不止一项这样的工作,那么当然可以并行启动它们,但您的管道本身很难并行化。将一个流拆分为并行流几乎是不值得的,而且同步和合并可能会非常痛苦。有时您只需要接受多核并不能帮助您完成正在运行的每一项任务。

一般来说,shell中的并行化主要应该是在独立进程的层面上。

相关内容