このbashスクリプトをどのように並列に実行できますか?

このbashスクリプトをどのように並列に実行できますか?

より効率的にするにはこれが必要です

現在のラインに応じて最大20時間かかります(かなり大きなMCSデータセットです)。

  • ビッグデータファイルを「ショット」に分割
  • forループに使用する各レンズ名のリストを作成します。
  • 各ショットを繰り返し、同じプロセスを実行します。
  • 以前と同じ行を持ちますが、処理するために各ショットを新しいデータファイルに追加します。この場合、データを繰り返しフィルタリングするので、並列に実行できると思いました。

すべてのSUコマンドとforループのすべての内容を無視できます。並列に実行する方法だけを知ることができます(例:32ノード)。これは私にとって比較的新しいテーマなので、詳細な説明をしていただきありがとうございます!

スクリプト:

#! /bin/bash    
# Split the input file into one file for each shot. NB mustclose each o/p file at the earliest opportunity otherwise it will crash!
susplit <$1 key=fldr stem=fldr_ verbose=1 close=1

# Create a list of shot files
ls fldr* > LIST

# Loop over each shot file; suppress direct wave; write to new concatenated output file
for i in `cat LIST`; do
    echo $i
    suchw key1=tstat key2=tstat a=200 < $i | suwind key=tracf min=10 max=400 tmin=0 tmax=6 | suweight a=0 | suresamp rf=4 | sustatic hdrs=1 sign=-1 | sureduce rv=1.52 | sumedian median=1 xshift=0 tshift=0 nmed=41 | suflip flip=3 | sureduce rv=1.52 | suflip flip=3 | suresamp rf=0.25 | suweight inv=1 a=0 | sustatic hdrs=1 sign=1 >> $2
done

# Tidy up files by removing single shot gathers and LIST
rm -f fldr* LIST &

ベストアンサー1

私はこれがfor並列化したいループであると仮定します。

#! /bin/bash    
# Split the input file into one file for each shot. NB mustclose each o/p file at the earliest opportunity otherwise it will crash!
susplit <$1 key=fldr stem=fldr_ verbose=1 close=1

sucit() {
    i=$1
    echo $i
    suchw key1=tstat key2=tstat a=200 < $i | suwind key=tracf min=10 max=400 tmin=0 tmax=6 | suweight a=0 | suresamp rf=4 | sustatic hdrs=1 sign=-1 | sureduce rv=1.52 | sumedian median=1 xshift=0 tshift=0 nmed=41 | suflip flip=3 | sureduce rv=1.52 | suflip flip=3 | suresamp rf=0.25 | suweight inv=1 a=0 | sustatic hdrs=1 sign=1
}
export -f sucit

parallel sucit ::: fldr* > $2

# Tidy up files by removing single shot gathers and LIST
rm -f fldr* LIST &

状況に応じてsusplitより迅速に処理できます。 "large_data_file"のショットが次から始まり<shot>\n終わった場合</shot>\n

sucpipe() {
    suchw key1=tstat key2=tstat a=200 | suwind key=tracf min=10 max=400 tmin=0 tmax=6 | suweight a=0 | suresamp rf=4 | sustatic hdrs=1 sign=-1 | sureduce rv=1.52 | sumedian median=1 xshift=0 tshift=0 nmed=41 | suflip flip=3 | sureduce rv=1.52 | suflip flip=3 | suresamp rf=0.25 | suweight inv=1 a=0 | sustatic hdrs=1 sign=1
}
export -f sucpipe

parallel --block -1 --recstart '<shot>\n' --recend '</shot>\n' --pipepart -a $1 sucpipe > $2

大容量ファイルをn個のチャンクに分割しようとします。ここで、nはコア数です。分割はすぐに実行されるため、一時ファイルは最初に書き込まれません。その後、GNU Parallel は各チャンクを sucpipe に渡します。

大容量ファイルがバイナリ(つまりテキストではない)で、ヘッダーが3200バイト、レコード長が1000バイトの場合、次のように機能します。

parallel -a bigfile  --pipepart --recend '' --block 1000 --header '.{3200}' ...

詳しくはこのチュートリアルをご覧ください。man parallel_tutorialコマンドラインが役に立ちます。

おすすめ記事