BASH: 병렬로 실행

BASH: 병렬로 실행

METHODS동일한 길이의 3개 배열( , INFILES및 ) 을 입력으로 받아들이는 bash 스크립트가 있습니다 OUTFILES.

METHODS[i]이 스크립트는 모든 index() 문제를 해결 INFILES[i]하고 결과를 .OUTFILES[i]i0 <= 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 = 61970개의 사용 가능한 프로세서가 있는 클러스터에 이 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[@]}"

주변에서 쇼핑하는 데 한 시간을 보내세요 man parallel_tutorial. 당신의 명령줄은 당신을 좋아할 것입니다.

답변2

검토 요약: 머신은 빠르지만 모든 것을 병렬로 실행하기에는 메모리가 부족합니다. 또 다른 문제는 읽어야 할 데이터의 양이 많고 디스크 대역폭이 충분하지 않아 CPU가 데이터를 기다리는 대부분의 시간을 유휴 상태로 유지한다는 점이다.

작업을 재정렬하는 것이 도움이 될 수 있습니다.

데이터를 압축하면 효과적인 디스크 I/O 대역폭이 증가할 수 있는지 여부는 연구되지 않았습니다.

관련 정보