15

10 個のコアにアクセスできるマシンにアクセスできますが、実際にそれらを使用したいと考えています。私が自分のマシンで行うことに慣れているのは、次のようなものです。

for f in *.fa; do
  myProgram (options) "./$f" "./$f.tmp"
done

これを実行したいファイルが 10 個あります。それらを blah00.fa、blah01.fa、... blah09.fa と呼びましょう。

このアプローチの問題は、myProgram が一度に 1 つのコアしか使用しないことです。マルチコア マシンでこのように実行すると、一度に 1 つのコアを 10 回使用することになります。その最大能力。

10 個の .fa ファイルすべてを同時に実行するようにスクリプトを変更するにはどうすればよいですか? Run a looped process in bash across multiple coresを見ましたが、そこからコマンドを取得して、必要なことを正確に行うことができませんでした。

4

3 に答える 3

12

あなたが使用することができます

for f in *.fa; do
    myProgram (options) "./$f" "./$f.tmp" &
done
wait

これにより、すべてのジョブが並行して開始され、次に進む前にすべてのジョブが完了するまで待機します。コアよりも多くのジョブがある場合は、それらすべてを開始し、OS スケジューラにプロセスのスワップインとアウトを心配させます。

変更の 1 つは、一度に 10 個のジョブを開始することです。

count=0
for f in *.fa; do
    myProgram (options) "./$f" "./$f.tmp" &
    (( count ++ ))        
    if (( count = 10 )); then
        wait
        count=0
    fi
done

parallelただし、古いジョブが終了すると新しいジョブを開始できず、10 個のジョブを開始する前に古いジョブが終了したかどうかを検出できないため、これは使用に劣ります。wait単一の特定のプロセスまたはすべてのバックグラウンド プロセスを待機できますが、バックグラウンド プロセスの任意のセットのいずれかが完了しても通知されません。

于 2013-03-11T16:55:08.093 に答える
8

GNU Parallel を使用すると、次のことができます。

parallel myProgram (options) {} {.}.tmp ::: *.fa

から: http://git.savannah.gnu.org/cgit/parallel.git/tree/README

= フルインストール =

GNU Parallel のフル インストールは次のように簡単です。

./configure && make && make install

root でない場合は、~/bin をパスに追加して、~/bin および ~/share にインストールできます。

./configure --prefix=$HOME && make && make install

または、システムに「make」がない場合は、src/parallel src/sem src/niceload src/sql をパスのディレクトリにコピーするだけです。

= 最小限のインストール =

並列が必要で、「make」がインストールされていない場合 (システムが古いか、Microsoft Windows である可能性があります):

wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
chmod 755 parallel
cp parallel sem
mv parallel sem dir-in-your-$PATH/bin/

詳細については、紹介ビデオをご覧ください: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

于 2013-03-11T20:56:14.170 に答える
0
# Wait while instance count less than $3, run additional instance and exit
function runParallel () {
    cmd=$1
    args=$2
    number=$3
    currNumber="1024"
    while true ; do
        currNumber=`ps -e | grep -v "grep" | grep " $1$" | wc -l`
        if [ $currNumber -lt $number ] ; then
            break
        fi
        sleep 1
    done
    echo "run: $cmd $args"
    $cmd $args &
}

loop=0
# We will run 12 sleep commands for 10 seconds each 
# and only five of them will work simultaneously
while [ $loop -ne 12 ] ; do
    runParallel "sleep" 10 5
    loop=`expr $loop + 1`
done
于 2015-02-11T11:52:36.227 に答える