METHODS
同じ長さの3つの配列(、INFILES
および)を入力として受け入れるbashスクリプトがありますOUTFILES
。
METHODS[i]
このスクリプトは、すべてのindex()の問題を解決し、INFILES[i]
結果を 。OUTFILES[i]
i
0 <= i <= length-1
の各要素は、METHODS
次の形式の文字列です。
$HOME/program/solver -a <method>
ここでソルバーは、次のように呼び出せるプログラムです。
$HOME/program/solver -a <method> -m <input file> -o <output file> --timeout <timeout in seconds>
このスクリプトはすべての問題を解決しました平行線そして、各インスタンスの実行時間制限を1時間に設定します(ただし、いくつかの問題をすばやく解決する方法はいくつかあります)。
#!/bin/bash
source METHODS
source INFILES
source OUTFILES
start=`date +%s`
## Solve in PARALLEL
for index in ${!OUTFILES[*]}; do
(alg=${METHODS[$index]}
infile=${INFILES[$index]}
outfile=${OUTFILES[$index]}
${!alg} -m $infile -o $outfile --timeout 3600) &
done
wait
end=`date +%s`
runtime=$((end-start))
echo "Total runtime = $runtime (s)"
echo "Total number of processes = ${#OUTFILES[@]}"
上記ではlength = 619
、70個の使用可能なプロセッサを持つクラスタにこのbashを送信し、すべての作業を完了するのに最大9時間かかります。しかし、実際にはそうではありません。このコマンドを使用してtop
調査した結果、2~3個のプロセスのみ実行中(状態=R
)、他のすべてのプロセスは休止状態(状態=D
)であることがわかりました。
私は何が間違っていましたか?
しかも私も学びました。GNUパラレル並列ジョブの実行に適しています。上記のタスクを実行するためにどのように使用できますか?
助けてくれてありがとう!
修正する:GNU並列性に対する私の最初の試み:
アイデアは、すべてのコマンドをファイルに書き込み、GNU Parallelを使用して実行することです。
#!/bin/bash
source METHODS
source INFILES
source OUTFILES
start=`date +%s`
## Write to file
firstline=true
for index in ${!OUTFILES[*]}; do
(alg=${METHODS[$index]}
infile=${INFILES[$index]}
outfile=${OUTFILES[$index]}
if [ "$firstline" = true ] ; then
echo "${!alg} -m $infile -o $outfile --timeout 3600" > commands.txt
firstline=false
else
echo "${!alg} -m $infile -o $outfile --timeout 3600" >> commands.txt
fi
done
## Solve in PARALLEL
time parallel :::: commands.txt
end=`date +%s`
runtime=$((end-start))
echo "Total runtime = $runtime (s)"
echo "Total number of processes = ${#OUTFILES[@]}"
どう思いますか?
アップデート2:私はGNUパラレルを使用していますが、同じ問題があります。出力は次のとおりですtop
。
top - 02:05:25 up 178 days, 8:16, 2 users, load average: 62.59, 59.90, 53.29
Tasks: 596 total, 7 running, 589 sleeping, 0 stopped, 0 zombie
Cpu(s): 12.9%us, 0.9%sy, 0.0%ni, 63.3%id, 22.9%wa, 0.0%hi, 0.1%si, 0.0%st
Mem: 264139632k total, 260564864k used, 3574768k free, 4564k buffers
Swap: 268420092k total, 80593460k used, 187826632k free, 53392k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
28542 khue 20 0 7012m 5.6g 1816 R 100 2.2 12:50.22 opengm_min_sum
28553 khue 20 0 11.6g 11g 1668 R 100 4.4 17:37.37 opengm_min_sum
28544 khue 20 0 13.6g 8.6g 2004 R 100 3.4 12:41.67 opengm_min_sum
28549 khue 20 0 13.6g 8.7g 2000 R 100 3.5 2:54.36 opengm_min_sum
28551 khue 20 0 11.6g 11g 1668 R 100 4.4 19:48.36 opengm_min_sum
28528 khue 20 0 6934m 4.9g 1732 R 29 1.9 1:01.13 opengm_min_sum
28563 khue 20 0 7722m 6.7g 1680 D 2 2.7 0:56.74 opengm_min_sum
28566 khue 20 0 8764m 7.9g 1680 D 2 3.1 1:00.13 opengm_min_sum
28530 khue 20 0 5686m 4.8g 1732 D 1 1.9 0:56.23 opengm_min_sum
28534 khue 20 0 5776m 4.6g 1744 D 1 1.8 0:53.46 opengm_min_sum
28539 khue 20 0 6742m 5.0g 1732 D 1 2.0 0:58.95 opengm_min_sum
28548 khue 20 0 5776m 4.7g 1744 D 1 1.9 0:55.67 opengm_min_sum
28559 khue 20 0 8258m 7.1g 1680 D 1 2.8 0:57.90 opengm_min_sum
28564 khue 20 0 10.6g 10g 1680 D 1 4.0 1:08.75 opengm_min_sum
28529 khue 20 0 5686m 4.4g 1732 D 1 1.7 1:05.55 opengm_min_sum
28531 khue 20 0 4338m 3.6g 1724 D 1 1.4 0:57.72 opengm_min_sum
28533 khue 20 0 6064m 5.2g 1744 D 1 2.1 1:05.19 opengm_min_sum
(上記のopengm_min_sum
内容ですsolver
)
一部のプロセスでは、あまりにも多くのリソースが消費され、他のプロセスには残りのリソースがないため、D状態に移行するようです。
答え1
バージョン 20160422 以降、次のことができます。
## Solve in PARALLEL
parallel {1} -m {2} -o {3} --timeout 3600 ::: "${METHODS[@]}" :::+ "${INFILES[@]}" :::+ "${OUTFILES[@]}"
以前のバージョンがある場合:
## Solve in PARALLEL
parallel --xapply {1} -m {2} -o {3} --timeout 3600 ::: "${METHODS[@]}" ::: "${INFILES[@]}" ::: "${OUTFILES[@]}"
近くで買い物をするのに1時間を過ごしてくださいman parallel_tutorial
。あなたのコマンドラインはあなたを愛するでしょう。
答え2
レビューの概要:マシンは高速ですが、すべてを並列に実行するのに十分なメモリがありません。もう1つの問題は、読み取る必要があるデータ量が多く、ディスク帯域幅が不足しているため、CPUがデータを待つほとんどの時間をアイドル状態に保つことです。
タスクを並べ替えると役に立ちます。
データを圧縮すると、効果的なディスクI / O帯域幅が増加する可能性があるかどうかは研究されていません。