如何有效地使用GNU并行


8

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

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

pv --rate在这里用于测量管道吞吐量。在我的机器上,解压缩后约为420Mb / s。

现在,我正在尝试使用GNU parallel做并行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选项的不同值。在这一点上没有任何帮助。

我究竟做错了什么?

Answers:


9

我真的很惊讶您使用GNU Parallel's达到270 MB / s --pipe。我的测试通常最大速度约为100 MB / s。

您的瓶颈很可能在GNU Parallel中:--pipe效率不是很高。--pipepart但是,是:在这里,每个CPU内核的速度为1 GB / s。

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

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

例:

parallel --pipepart -a bigfile --block 100M grep somepattern

1
谢谢。有什么原因会导致--pipe效率低下?我的意思是说这是某种基本问题,还是更多具体实施问题。
Denis Bazhenov

2
是的:GNU Parallel是用perl编写的,--pipe每个字节都必须经过单个进程,该进程必须对每个字节进行一点处理。对于--pipepart大多数字节,中央进程永远不会看到:它们由产生的作业处理。因为只有几行是瓶颈,--pipe所以我欢迎C / C ++编码器重写该部分,然后再将其运行在具有C编译器的人员手中。
Ole Tange'Feb

2

grep非常有效-并行运行没有任何意义。在您的命令中,仅解压缩需要更多的cpu,但这是无可比拟的。

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

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

如果您希望加快此操作的速度-查找瓶颈所在-可能是解压缩(然后有助于使用其他解压缩工具或更好的cpu)或-从磁盘读取(然后帮助使用其他解压缩工具或更好的磁盘系统)。

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


1
确实,这是我的情况。CPU占用率很高的Java进程代替了grep。我将问题简化了一点。而且,并行占用大量CPU并不能为Java进程提供大量工作。
丹尼斯·巴珍诺夫

1

减压是这里的瓶颈。如果未在内部并行执行解压缩,则您将无法自行实现。如果您有多个这样的工作,那么当然可以并行启动它们,但是您的管道本身很难并行化。将一个流拆分为并行流几乎是不值得的,并且对于同步和合并可能非常痛苦。有时,您只需要接受多个内核对您运行的每个任务都无济于事。

通常,shell中的并行化应主要在独立进程的级别上。


1
如果使用,减压似乎不是瓶颈parallel。我同意这肯定是在第一种情况下(没有并行),但是在第二种情况下(并行),瓶颈在并行方面。这是根据观察发现,通过进行测量,吞吐量显着下降pv。如果瓶颈处于减压状态,那么无论您添加到管道中的什么,吞吐量都不会改变。我想这是对吞吐量的非常直观的定义-限制吞吐量最大的因素。
Denis Bazhenov

1
grep可能是如此之快,以至于其完成速度快于parallel可写入其管道的速度。在这种情况下,大多数grep进程parallel将全天候工作,以等待获得更多信息,而将它们全天候工作以将这些块多路复用到几个管道中(这是额外的IO操作,如果缓冲区已满,甚至可能会解压缩)。您是否也尝试使用该--block参数?默认情况下,1M这样直到一个grep获取1M数据,其余几乎可以肯定已经完成。因此,我们回到了一个事实,那就是将其并行化是没有意义的。
Orion

1
是的,我已经尝试过使用大和小块大小的此选项。以及-N/ -L选项的不同值。似乎默认选项非常接近我所遇到的局部最优值:)
Denis Bazhenov

1
尝试使用和不使用pv(使用time)对它进行计时。这样,您可以查看pv自身是否正在降低速度。如果是这样,那么parallel将数据复制到管道中肯定是额外的开销。而且无论如何,我都可以肯定,grep在这种情况下,它几乎是实时的,尤其是当模式是一个没有太多回溯的简单字符串时。此外,parallel将交错并弄乱grep输出。
Orion

1
我会交叉检查它pv本身不会导致问题,谢谢您的建议。
Denis Bazhenov
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.