假设我想找到压缩文本文件中的所有匹配项:
$ 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中的并行化主要应该是在独立进程的层面上。