2017-01-29 18 views
1

csplitを使って4つのファイルを自動的に分割し、同じコマンドをバックグラウンドで実行する4つのシェルプログラムをnohupでループする1つのシェルプログラムと、この4つのプロセスの完了をループで調べ、最後にcat output1.txtを探しました。 ... output4.txt> finaloutput.txtUnixコマンドの並列実行?

しかし、私はこのコマンドについて知りに来たparallelと私は大きなファイルでこれを試しましたが、期待どおりに動作していないようです。このファイルには、以下のコマンドの出力である -

for i in $(seq 1 1000000);do cat /etc/passwd >> data.txt1;done 

time wc -l data.txt1 
10000000 data.txt1 

real 0m0.507s 
user 0m0.080s 
sys  0m0.424s 

並列

time cat data.txt1 | parallel --pipe wc -l | awk '{s+=$1} END {print s}' 
10000000 

real 0m41.984s 
user 0m1.122s 
sys  0m36.251s 

と、私は2GBのファイル(〜1000万)を記録するためにこれをしようとしたときには20分以上かかりました。

は、このコマンドは、はい..あなたは、パラレルから利益を得るために、マシン上で複数の物理コアが必要になります要するに

nproc --all 
1 
+0

私たちにアクセス権を与えることができるdata.txt1を使用するように例を変更することはできますか?あなたのタイミングは非常に極端なので、実行しているマシンについてさらに知る必要があります。 –

+0

@OleTange - 要求されたとおり、私はファイルデータのロジックを添付しました。このコマンドを開発したのはあなたですか? –

+1

私は著者です。お使いのコンピュータと別のコンピュータで以下に示すテストを試してください。私はあなたのコンピュータが何らかの形で壊れていると思います。 –

答えて

1

--pipeは( - 何かがあなたのシステムに非常に間違っていない、あなたが測定されているスケールでいえ)非効率的です。 1 GB /秒(合計)のオーダで配信できます。

--pipepartは、逆に、非常に効率的です。ディスクが十分に高速であれば、コアあたり1 GB /秒のオーダで配信できます。これは、処理の最も効率的な方法であるはずですdata.txt1。これは、CPUコアごとに1つのブロックにしてdata.txt1を分割し、各コア上で実行されているwc -lにこれらのブロックを供給します:

parallel --block -1 --pipepart -a data.txt1 wc -l 

block -1が機能するためにあなたがバージョン20161222以降が必要です。

これらは私の古いデュアルコアのノートパソコンからのタイミングです。seq 200000000は1.8GBのデータを生成します。

$ time seq 200000000 | LANG=C wc -c 
1888888898 

real 0m7.072s 
user 0m3.612s 
sys  0m2.444s 

$ time seq 200000000 | parallel --pipe LANG=C wc -c | awk '{s+=$1} END {print s}' 
1888888898 

real 1m28.101s 
user 0m25.892s 
sys  0m40.672s 

ここでの時間は各1メガバイトのブロックのための新しいwc -cを産卵パラレルGNUのほとんどが原因です。ブロックサイズを大きくすると、より速くそれを作る:

$ seq 200000000 > data.txt1 
$ time parallel --block -1 --pipepart -a data.txt1 LANG=C wc -c | awk '{s+=$1} END {print s}' 
1888888898 

real 0m2.242s 
user 0m0.424s 
sys  0m2.880s 

だから私の古いラップトップ上で、私は2.2秒に1.8ギガバイトを処理することができます。

$ time seq 200000000 | parallel --block 10m --pipe LANG=C wc -c | awk '{s+=$1} END {print s}' 
1888888898 

real 0m26.269s 
user 0m8.988s 
sys  0m11.920s 

$ time seq 200000000 | parallel --block 30m --pipe LANG=C wc -c | awk '{s+=$1} END {print s}' 
1888888898 

real 0m21.628s 
user 0m7.636s 
sys  0m9.516s 

としては、ファイル内のデータを持っている場合--pipepartがはるかに高速で述べました。

コアが1つしかなく、作業がCPUに依存する場合、並列化は役に立ちません。単一のコアマシン上で並列化することは、大部分の時間が待機(例えば、ネットワークを待っている)に費やされる場合には意味をなさえることができる。

しかし、コンピュータからのタイミングによって、何かが間違っていることがわかります。あなたのプログラムを別のコンピュータでテストすることをお勧めします。

+0

--diskpartに通知するようにしてくれてありがとうございます。私はそれを知らなかった。 :) – Mandar

0

(私は現在、シングルコアシステムを使用しています)、マルチコアシステム上で動作します。あなたの仕事を理解するだけです。次はあなたが

file1 is a 10,000,000 line file 

split into 4 files > 
file1.1 > processing > output1 
file1.2 > processing > output2 
file1.3 > processing > output3 
file1.4 > processing > output4 

>> cat output* > output 
________________________________ 

をするつもり、あなたが中央部を並列化すると同時に、4つのコア(うまくいけば4つのコア)上でそれを実行したいものです。私は正しいですか?私はあなたが-jは、プロセッサの数のためである(擬似コードの警告)を指定して、コマンドファイルと使用の1

parallel --jobs 4 "processing code on the file segments with sequence variable {}" ::: 1 2 3 4 

ためのコードを書くより良い方法で、GNU平行を使用することができると思います。

UPDATE は、なぜあなたはあなたのfile1.1 1.2 1.3と1.4の範囲内の順次実行のための並列命令をしようとしています?あなたは

parallel 'for i in $(seq 1 250000);do cat file1.{} >> output{}.txt;done' ::: 1 2 3 4 
上記のコードは、4つのコア

for i in $(seq 1 250000);do cat file1.1 >> output1.txt;done 
for i in $(seq 1 250000);do cat file1.2 >> output2.txt;done 
for i in $(seq 1 250000);do cat file1.3 >> output3.txt;done 
for i in $(seq 1 250000);do cat file1.4 >> output4.txt;done 

上で並列にcsplitコマンドからあなたの4つの分割されたファイルを実行します

をコード化しているとして、それは私がかなり確信している通常の逐次処理とします - Oleによって上で示唆されたdiskpartはそれを行うより良い方法です。 HDDからの高速データアクセスがあることを前提としています。

+0

私はあなたのコマンドを試しましたが、それは動作していません、それはエラーをスローしています(ファイルやディレクトリなし) time cat data.txt1 |パラレル - ジョブ4 wc -l | awk '{s + = $ 1} END {print s}' コマンドはうまくいきましたが、時間がかかります - time cat data.txt1 |パラレル - パイプwc -l | awk '{s + = $ 1} END {print s}' –

+0

もう一つのボトルネックはHDDの読み込み速度になります。通常のHDDに4つのスレッドを起動している場合(レイドなし)、速度が遅くなる可能性があります。 Btwなぜあなたは猫のdata.txt1をパラレルにパイプしているのですか?最初にfile1.1 1.2 1.3と1.4を作成できます。それが完了したら、同時に4つのファイルすべてに対して並列実行を作成し、出力を取得します.2.3.3.4 ...そのプロセスが完了するまで待ちます。出力を連結します。私の推測では、すべてのパラレルを並列に使用しています。 – Mandar

関連する問題