for
次のコードのループを並列化したいと思います。どうすればいいですか?
#!/bin/bash
N=$1
n=$2
for (( i=1; i<=$N; i++ )); do
min=100000000000000 //set min to some garbage value
for (( j=1; j<=$n; j++ )); do
val=$(/path/to/a.out)
val2=`echo $val | bc`
if (( $val2 < $min )); then
min=$val2;
fi
done
arr=("${arr[@]}" "$min")
done
ベストアンサー1
#!/bin/bash
# set -x # debug version
N=${1:-123}
n=${2:-45}
workers=${workers:-${3:-10}}
((workers < 1)) && ((workers = 1))
((workers > 20)) && ((workers = 20))
((min=100000000000000)) #set min to some garbage value
work() {
for i in ${*}; do
for (( j=1; j<=${n}; j++ )); do
val=$(/path/to/a.out)
val2=$(echo ${val} | bc)
(( val2 < min )) && (( min = val2 ));
done
echo ${min}
# # debug version
# echo ${i} ${j} ${min}
done
}
# --
arr=($(
seq ${N} | xargs -n$[N/workers + 1] | while read i; do
work ${i} &
done
wait
))
echo ${arr[*]}
# --
# # debug version
# seq ${N} | xargs -t -n$[N/workers + 1] | while read i; do
# work ${i} &
# done
# wait
パラメータ化された数のプロセスを作成するときは、常にワーカースレッドを使用し、作成できるワーカースレッドの最大数を制限してください。。
xargs -n | while read
リストをまとめて繰り返す簡単な方法です。
seq
1からNまでの数値リストを作成します。xargs -n
リストを N/workers+1 バッチに分割します。- たとえば、N = 100workers = 10は、最大11個の数字(1から100まで)の10行を生成します。
while read i
各数値行をお読みください。work ${i} &
一連の数字で関数を呼び出すだけですwork
。${i}
デバッグ用にコメント付きのデバッグコードを追加しました。echo
デバッグバージョンに置き換えて、それらの間のコードを# --
デバッグバージョンに置き換えることで、一括してどのように機能するかを確認できます。set -x
ファイルにリダイレクトできるより詳細なデバッグ出力のために、このエントリのコメントを外します。
さまざまなパラメータを使用してデバッグバージョンを実行して、その動作を確認してください。
parallel.sh 223 5 1
parallel.sh 223 5 5
parallel.sh 223 5 10
parallel.sh 223 5 20
min
免責事項:このコードはワーカープロセス間で値を同期しません。最小値を得ることはひどいことではありません。これを行うことができます:
parallel.sh 223 5 20 | tr ' ' '\n' | sort -n | head -1
あるいは、スクリプト自体に同じ内容を追加するだけです。
echo ${arr[*]} | tr ' ' '\n' | sort -n | head -1