Bash の連続および並列ループ/コマンド

Bash の連続および並列ループ/コマンド

自分で作成した Python ツールを使用して、いくつかのシミュレーションを実行したいと思います。問題は、異なるパラメータや引数などを使用して、複数回呼び出す必要があることです。

for今のところ、タスクには次のように複数のループを使用しています。

for simSeed in 1 2 3 4 5
do
    for launchPower in 17.76 20.01 21.510 23.76
    do
        python sim -a $simSeed -p $launchPower
    done
done

シミュレーションを同時に実行するために、&シミュレーターを呼び出す行の末尾に を追加します。

python sim -a $simSeed -p $launchPower &

この方法を使用すると、複数のシードを実行できます。ただし、コンピューターのメモリが限られているため、内側のforループを並列に起動し、外側のforループを順番に起動するように上記のスクリプトを書き直したいと思います。

たとえば、 について、に等しいsimSeed = 15 つの異なるプロセスを実行したいとします。この部分が完了したらすぐに、 についてスクリプトを実行し、に等しい5 つの異なる並列プロセスを再度実行します。launchPower17.76 20.01 21.510 23.76simSeed = 2launchPower17.76 20.01 21.510 23.76

このタスクを達成するにはどうすればいいでしょうか?

要約:

外側のループを順番に実行し、内側のループを並列に実行して、内側のループの最後の並列プロセスが終了すると、外側のループが次の反復に移動するようにします。

答え1

GNU parallel には、ジョブを並列で開始するときにリソースの使用を制限するオプションがいくつかあります。

2つのネストされたループの基本的な使い方は次のようになります。

parallel python sim -a {1} -p {2} ::: 1 2 3 4 5 ::: 17.76 20.01 21.510 23.76

例えば、最大5つのジョブを同時に起動したい場合は、次のようにします。

parallel -j5 python <etc.>

あるいは、--memfree十分なメモリが空いている場合にのみ新しいジョブを開始するオプションを使用することもできます(例:少なくとも256 MByte)。

parallel --memfree 256M python <etc.>

最後のオプションでは、メモリが指定された「予約」値の 50% を下回ると、最後に開始されたジョブが強制終了されることに注意してください (ただし、キャッチアップのために自動的に再キューに入れられます)。

答え2

コメントで述べたように、これはまさに GNUparallelの目的です。

for simSeed in 1 2 3 4 5
do
    ## Launch 5 instances in parallel 
    parallel -j5 python sim -a $simSeed -p {} ::: 17.76 20.01 21.510 23.76
done

答え3

それぞれのプロセス ID を保存してwait終了させることができます。

for simSeed in {1..5}; do
  pids=()
  for launchPower in 17.76 20.01 21.510 23.76; do
    python sim -a $simSeed -p $launchPower &
    pids+=($!)
  done
  wait ${pids[@]}
done

pids内部ループのバックグラウンド ジョブのプロセス ID の配列です。${pids[@]}配列のすべての要素が wait コマンドに渡されます。

関連情報