Bash의 루프 병렬화

Bash의 루프 병렬화

특정 디렉터리를 가져와 특정 입력 파일에 대해 특정 계산을 수행하는 루프가 있는 Bash 스크립트가 있습니다. 그런 다음 해당 디렉터리에서 종료되고 다른 입력 파일을 사용하여 다른 디렉터리에서 동일한 작업을 수행합니다. 계산에 시간이 많이 걸리고 병렬화하고 싶습니다.

내 스크립트를 어떻게 수정할 수 있나요? 이 작업을 수행할 수 있는 옵션이 있습니까?

myscript.sh

cd MainDir
for dir in *
  do
      cd ${dir}
      LD_LIBRARY_PATH="$software"/ "$software"/calc -i /home/files/"$dir.txt" -l /home/Str/Art.pdb -a 5.0 -rf /home/file/prot -cpu 1 opt -w ${dir}_res > ${dir}_WPA.log
     cd .. 
  done

-cpu 명령을 사용하여 CPU 사용량을 나타냅니다. 마음대로 사용할 수 있는 CPU가 많은데 더 많은 작업을 병렬로 처리하려면 어떻게 해야 합니까?

예를 들어, 세 개의 서로 다른 입력 파일이 있는 경우 다음 명령을 함께(다른 디렉터리에서) 실행하고 싶습니다.

cd 1
LD_LIBRARY_PATH="$software"/ "$software"/calc -i /home/files/1.txt -l /home/Str/Art.pdb -a 5.0 -rf /home/file/prot -cpu 1 opt -w 1_res > 1_WPA.log
-----------
cd 2
LD_LIBRARY_PATH="$software"/ "$software"/calc -i /home/files/2.txt -l /home/Str/Art.pdb -a 5.0 -rf /home/file/prot -cpu 1 opt -w 2_res > 2_WPA.log
-----------
cd 3
LD_LIBRARY_PATH="$software"/ "$software"/calc -i /home/files/3.txt -l /home/Str/Art.pdb -a 5.0 -rf /home/file/prot -cpu 1 opt -w 3_res > 3_WPA.log

누구든지 나를 도와줄 수 있나요? 감사해요.

답변1

&명령 끝에 다음을 추가하여 백그라운드로 보낼 수 있습니다 .

for i in 1 2 3 4; do
    (
        cd dir
        command
        [...]
    ) &
done
wait # pause until all background processes are terminated

답변2

그리고 zsh:

do-calc() (
  cd -- $1 &&
    LD_LIBRARY_PATH=$software/ $software/calc \
      -i /home/files/$1.txt \
      -l /home/Str/Art.pdb \
      -a 5.0 \
      -rf /home/file/prot -cpu 1 opt -w ${1}_res > ${1}_WPA.log
)

autoload zargs
cd MainDir && zargs -rn1 -P12 -- ./*(N-/) -- do-calc

이러한 기능 중 최대 12개를 do-calc병렬로 실행하세요.

Korn과 유사한 쉘(예: bash - GNU 쉘) 및 프로세스 교체를 지원하는 GNU 유틸리티의 경우 다음과 같이 수행할 수 있습니다.

export software
cd MainDir &&
  xargs -0rn1 -P12 -a <(
      LC_ALL=C find . -maxdepth 1 ! -name '.*' -xtype d -print0 |
        sort -z
    ) sh -c '
      cd -- "$1" &&
        LD_LIBRARY_PATH="$software/" "$software/calc" \
          -i "/home/files/$1.txt" \
          -l /home/Str/Art.pdb \
          -a 5.0 \
          -rf /home/file/prot -cpu 1 opt -w "${1}_res" > "${1}_WPA.log"
      ' sh

답변3

GNU Parallel을 사용하면 다음과 같은 작업을 수행할 수 있습니다.

doit() {
      dir="$1"
      cd ${dir}
      LD_LIBRARY_PATH="$software"/ "$software"/calc -i /home/files/"$dir.txt" -l /home/Str/Art.pdb -a 5.0 -rf /home/file/prot -cpu 1 opt -w ${dir}_res > ${dir}_WPA.log
}
export -f doit

cd MainDir
parallel doit  ::: *

그러면 CPU 스레드당 하나의 작업이 실행됩니다. 이것이 마음에 들지 않으면 13개의 작업을 병렬로 실행하도록 조정할 수 있습니다.

parallel -j13 doit  ::: *

":::"과 같은 파일이 있는 경우 다음을 수행해야 합니다.

LC_ALL=C find . -maxdepth 1 ! -name '.*' -xtype d -print0 |
  parallel -0 doit

또는:

parallel --argsep /// -j13 doit  /// *

관련 정보