BASH:並行執行
我有一個 bash 腳本,它將三個長度相等的數組作為輸入
METHODS
:INFILES
和OUTFILES
.此腳本將
METHODS[i]
解決問題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
. 我將這個 bash 送出給一個有 70 個可用處理器的集群,它最多需要 9 個小時才能完成所有任務。然而,實際情況並非如此。使用該top
命令進行調查時,我發現只有兩三個程序在執行(state =R
),而其他所有程序都在休眠(state =D
)。請問我做錯了什麼?
此外,我了解到GNU 並行對於執行並行作業會更好。我如何將它用於上述任務?
非常感謝您的幫助!
**更新:**我第一次嘗試使用 GNU 並行:
想法是將所有命令寫入文件,然後使用 GNU 並行執行它們:
#!/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 狀態?
評論摘要:機器速度很快,但沒有足夠的記憶體來並行執行所有內容。另外這個問題需要讀取大量數據,磁碟頻寬不夠,所以cpu大部分時間都是空閒的等待數據。
重新安排任務會有所幫助。
尚未研究壓縮數據是否可以提高有效磁碟 I/O 頻寬。
從版本 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[@]}"
花一個小時走過
man parallel_tutorial
。您的命令行會因此而愛上您。