다수의 반복으로 for 루프를 병렬화

다수의 반복으로 for 루프를 병렬화

루프의 반복 횟수가 10^6과 같이 매우 클 수 있는 for 루프를 병렬화하고 싶습니다. 그래서 프로세스 대신 스레드를 생성할 수 있다면 더 좋을 것 같습니다. 어떻게 하나요? 코드는 아래와 같이 표시됩니다.

N=$1

for (( i=0; i < $N; i++ )); do

    ./random >> output /* in each iteration one random number is appended to
                          a file "output" */                                

done

답변1

  1. 쉘에서는 스레드를 생성할 수 없습니다.
  2. 여러 프로세스에서 동일한 파일에 쓰고 싶지 않습니다.
  3. random프로그램에서 숫자만 생성하는 경우
    • 루프가 바인딩될 만큼 충분히 빨라야 합니다.
    • 가능하다면 인수를 받아들이고 그 만큼의 숫자를 인쇄하도록 편집해야 합니다.
    • 실제 실행으로 인해 병목 현상이 발생하는 경우 숫자를 생성하는 방법을 다시 고려해야 합니다. 코드를 게시할 수도 있습니다.코드 검토.

만약 당신이 정말로진짜그래도 이 작업을 수행하려면 덩어리 단위로 수행하십시오.

for i in {0..9}; do
    for ((j = 1; j < $N/10; j++)); do
        ./random
    done > tmp$i &
    pid[$i]=$?
done
for i in {0..9}; do
    wait ${pid[$i]}
done
cat tmp{0..9} >> outfile

답변2

수동으로 새 스레드를 생성할 수 있는 쉘이 있는지는 모르겠습니다. 일반적으로 현재 쉘의 기존 스레드만 활용할 수 있습니다(또는 사실상 새 프로세스인 하위 쉘을 생성할 수 있습니다). python대신에 또는 다른 언어를 사용하세요 .

가능하더라도 이 정도 규모의 작업을 수행하기 위해 쉘 스크립트를 사용하는 것은 권장하지 않습니다. 10^6 반복을 실행할 때 성능 저하가 컴파일된 언어에 비해 상당히 클 수 있습니다.

답변3

언제나 그렇듯이 문제는 리소스 경합입니다. 동시에 실행되는 프로세스/스레드 수를 제한해야 합니다.

또한 동시 스레드가 있는지 여부는 수행될 처리 유형에 따라 크게 달라집니다. 메모리, CPU, I/O 등 좋은 프로그래밍 조합이 있다면 더 좋을 것입니다. 모든 하위 프로세스가 모든 CPU 작업을 수행하는 경우 10~20개의 하위 프로세스를 동시에 실행해도 속도가 향상되지 않습니다. 예를 들어 ssh를 사용하여 호출을 시작하고 다른 시스템에서 결과를 얻으려면 처리를 아웃소싱할 수 있습니다.

빠르고 더러운 첫 번째 패스는 다음과 같습니다.

N=$1 # max number to iterate on
shift # rest of command line is the command to run: e.g. "./random"
maxcount=10 # maximum in the pool
curcount=0  # how many currently in the pool
reaper () {
    wait
    curcount=`expr $curcount - 1`
}
spawnnext () {
    n=$1
    shift
    while [ $curcount -ge $maxcount ]; do
        sleep 1 # wait for a free slot in the pool
    done
    echo $n
    "$@" &
    curcount=`expr $curcount + 1`
}

trap 'reaper' CHLD

for (( i=0; i < $N; i++)); do
    spawnnext $i "$@"
done

참고: 아직 테스트하지 않았습니다. 단지 임시로 작성한 것입니다.

하지만 저는 Python과 같이 더 높은 수준의 더 나은 성능을 제공하는 언어에서 이 작업을 수행할 것입니다.https://stackoverflow.com/questions/3033952/python-thread-pool-similar-to-the-multiprocessing-pool

답변4

귀하의 작업이 난수를 생성하는 것이라면 다음을 수행하십시오.

perl -e 'for($t=0;$t<1000000;$t++) { print int(rand()*1000),"\n" }'

당신의 작업이 정말로 다른 것이라면, GNU Parallel을 사용할 수 있습니다:

parallel ./random :::: <(seq 1000000) > output

다음과 같이 간단하게 GNU Parallel을 설치할 수 있습니다.

wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
chmod 755 parallel

자세히 알아보려면 소개 비디오를 시청하세요.http://pi.dk/1

관련 정보