
圧縮されたテキストファイルですべての一致を探したいとしましょう。
$ 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
スループットは現在約260 Mb / sに低下しました。さらに興味深いのは、parallel
プロセス自体がCPUを多用することです。プロセスより多いgrep
(しかし未満gzcat
)。
編集1--block
:さまざまなチャンクサイズ()、-N
/オプション-L
の値を別々に試しました。現時点では私に役立つものは何もありません。
私は何が間違っていましたか?
答え1
私はあなたがGNU Parallelを使用しているという事実に本当に驚きました--pipe
。私のテストの最大速度は通常約100MB / sです。
GNU Parallelでは、ボトルネックが発生する可能性が高いです。--pipe
それほど効率的ではありません。--pipepart
ただし、ここではCPUコアあたり1GB/s程度を得ることができます。
残念ながら、使用にはいくつかの制限があります--pipepart
。
- ファイルは検索可能でなければなりません(つまり、パイプなし)。
- --recstart/--recend を使用してレコードの先頭を見つけることができる必要があります (つまり、圧縮ファイルはありません)。
- 行番号が不明です(したがって、4行のレコードが存在できません)。
例:
parallel --pipepart -a bigfile --block 100M grep somepattern
答え2
grepは非常に効率的です。並列に実行する必要はありません。命令の解凍にはさらにCPUが必要ですが、並列化することはできません。
入力を並列に分割するには、grepを介して一致する行を取得するよりも多くのCPUが必要です。
grepよりラインごとに多くのCPUが必要なものを使用したい場合は、状況が異なります。そうすれば、並列化はより意味があります。
速度を上げるには、ボトルネックがある場所を確認してください。解凍するか(他の解凍ツールやより良いCPUを使用するのに役立ちます)、ディスクから読み込むことをお勧めします(他の解凍ツールやより良いディスクシステムを使用するのに役立ちます)。
私の経験では、lzma(-2など)を使用してファイルを圧縮/圧縮解除する方が良い場合があります。 gzipより圧縮率が高いため、ディスクから読み取るのに必要なデータがはるかに少なく、速度も似ています。
答え3
ここでは減圧がボトルネックになります。解凍内に並列化がないと、直接実行することはできません。そのような作業が複数ある場合はもちろん並列で開始できますが、パイプライン自体は並列化するのが難しいでしょう。ストリームを並列ストリームに分割することはほとんど価値がなく、同期とマージは難しい場合があります。時には、複数のコアが実行中のすべてのタスクに役立つわけではないという事実を受け入れる必要があります。
一般的に言えば、シェルの並列化は主に独立したプロセスレベルで行われるべきです。