For döngüsünün paralelleştirilmesi


9

forAşağıdaki kodun döngülerini paralelleştirmek istiyorum . Bu nasıl yapılır?

#!/bin/bash
N=$1 
n=$2
for (( i=1; i<=$N; i++ )); do
  min=100000000000000  //set min to some garbage value
  for (( j=1; j<=$n; j++ )); do
    val=$(/path/to/a.out)
    val2=`echo $val | bc`  

      if (( $val2 < $min )); then
        min=$val2; 
      fi
  done
  arr=("${arr[@]}" "$min")
done


Yanıtlar:


10
#!/bin/bash
# set -x # debug version
N=${1:-123}
n=${2:-45}
workers=${workers:-${3:-10}}
((workers < 1)) && ((workers = 1))
((workers > 20)) && ((workers = 20))

((min=100000000000000))  #set min to some garbage value

work() {
  for i in ${*}; do
    for (( j=1; j<=${n}; j++ )); do
      val=$(/path/to/a.out)
      val2=$(echo ${val} | bc)
      (( val2 < min )) && (( min = val2 ));
    done
    echo ${min}
    # # debug version
    # echo ${i} ${j} ${min}
  done
}

# --
arr=($(
  seq ${N} | xargs -n$[N/workers + 1] | while read i; do
    work ${i} &
  done
  wait
))
echo ${arr[*]}
# --

# # debug version
# seq ${N} | xargs -t -n$[N/workers + 1] | while read i; do
#  work ${i} &
# done
# wait

Parametrelenmiş sayıda süreç üretirken daima işçileri kullanın ve ortaya çıkabilecek maksimum işçi sayısını sınırlayın .

xargs -n | while read listelerin toplu olarak yinelenmesinin basit bir yoludur.

  • seq 1'den N'ye kadar bir sayı listesi oluşturur.
  • xargs -n bu listeyi N / işçi + 1 grubuna böler.
    • örneğin N = 100 işçi = 10, 1'den 100'e kadar 11 sayıya kadar 10 satır üretecektir.
  • while read i her sayı satırını okur.
  • work ${i} &workfonksiyonu sadece ${i}sayı grubu ile çağırır .

Hata ayıklamak için yorumlanmış hata ayıklama kodu ekledim. Sadece echohata ayıklama sürümü ile değiştirin ve hata ayıklama sürümü ile arasındaki kodu # --ve toplu işlerde nasıl çalıştığını görebilirsiniz. set -xBir dosyaya yeniden yönlendirmek isteyebileceğiniz daha ayrıntılı bir hata ayıklama çıktısı için rahatsızlık .

Nasıl çalıştığını izlemek için hata ayıklama sürümünü farklı parametrelerle çalıştırın:

parallel.sh 223 5 1
parallel.sh 223 5 5
parallel.sh 223 5 10
parallel.sh 223 5 20

Yasal Uyarı: Bu kod, minçalışan işlemler arasındaki değeri eşitlemez . Minimum değeri elde etmek korkunç bir egzersiz değildir. Bu muhtemelen şunları yapar:

parallel.sh 223 5 20 | tr ' ' '\n' | sort -n | head -1

Veya aynısını betiğin kendisine ekleyin:

echo ${arr[*]} | tr ' ' '\n' | sort -n | head -1

Kodu açıklayabilir misiniz? Burada işçi ipliklerini nasıl kullandığınız net değil.
RIchard Williams

@prasenjit Tamamlandı. Umarım faydalı olur.
nicerobot

8

GNU Paralel Kullanımı:

#!/bin/bash

N=$1
n=$2

arr=($(
# Generate all combinations of 1..n and 1..N
parallel -k --tag /path/to/a.out {1} {2} '|' bc :::: <(seq $N) <(seq $n) |
  perl -ane 'BEGIN{$min=1e30} $last||=$F[0]; if($F[0] != $last) {print $min,"\n";$min=1e30;$last=$F[0]} $min = $F[2]<$min ? $F[2] : $min; END {print $min,"\n"}'
))
echo ${arr[*]}

Bu /path/to/a.out, her CPU'da çalışacaktır . Çıktı aşağıdaki gibi olacaktır:

1 1 19269
1 2 6158
1 3 2794
1 4 25104
2 1 13160
2 2 32683
2 3 12535
2 4 15197
3 1 8228
3 2 7673
3 3 8428
3 4 24463

Perl betiği ilk sütuna bakar ve aynı ilk sütuna sahip 3. sütunda minimum değeri bulur.

GNU Parallel'ı aşağıdaki yollarla kurabilirsiniz:

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

Daha fazla bilgi edinmek için giriş videolarını izleyin: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1


Son paragrafınızdaki bağlantı, ziyaretçiye özel bir hediye (reklam veya aldatmaca) kazandığını bildiren bir facebook görünümlü sayfaya bağlantı verir. Hiç video yok. Kaldırmalısın.
Marco
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.