Parallelisierung einer for-Schleife


9

Ich möchte die forSchleifen des folgenden Codes parallelisieren . Wie macht man das?

#!/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


Antworten:


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

Verwenden Sie immer Arbeiter, wenn Sie eine parametrisierte Anzahl von Prozessen erzeugen, und begrenzen Sie die maximale Anzahl von Arbeitern, die erzeugen können .

xargs -n | while read ist ein einfaches Mittel zum Iterieren von Listen in Stapeln.

  • seq Erstellt eine Liste mit Zahlen von 1 bis N.
  • xargs -n unterteilt diese Liste in N / Arbeiter + 1 Chargen.
    • Beispiel: N = 100 Arbeiter = 10 erzeugen 10 Zeilen mit bis zu 11 Zahlen von 1 bis 100.
  • while read i liest jede Zahlenzeile.
  • work ${i} &Ruft einfach die workFunktion mit einem ${i}Stapel von Zahlen auf.

Zum Debuggen habe ich auskommentierten Debug-Code hinzugefügt. Ersetzen Sie einfach echodie Debug-Version und den Code dazwischen # --durch die Debug-Version, und Sie können sehen, wie es bei Batches funktioniert. Kommentar set -xfür eine detailliertere Debug-Ausgabe, die Sie möglicherweise in eine Datei umleiten möchten.

Führen Sie einfach die Debug-Version mit verschiedenen Parametern aus, um zu sehen, wie sie funktioniert:

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

Haftungsausschluss: Dieser Code synchronisiert den minWert zwischen Arbeitsprozessen nicht. Das Erreichen des Mindestwerts ist keine schreckliche Übung. Dies wird wahrscheinlich tun:

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

Oder fügen Sie dem Skript selbst dasselbe hinzu:

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

Können Sie den Code erklären? Mir ist nicht klar, wie Sie hier Arbeitsthreads verwendet haben.
RIchard Williams

@prasenjit Fertig. Ich hoffe das ist hilfreich.
Nicerobot

8

Verwenden von GNU Parallel:

#!/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[*]}

Dies läuft /path/to/a.outauf jeder CPU. Die Ausgabe lautet wie folgt:

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

Das Perl-Skript betrachtet die erste Spalte und findet das Minimum in der dritten Spalte, die dieselbe erste Spalte enthält.

Sie können GNU Parallel einfach installieren, indem Sie:

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

Sehen Sie sich die Intro-Videos an, um mehr zu erfahren: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1


Der Link in Ihrem letzten Absatz verweist auf eine Facebook-Seite, die dem Besucher mitteilt, dass er ein exklusives Geschenk (Werbung oder Betrug) gewonnen hat. Es gibt keine Videos. Sie sollten es entfernen.
Marco
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.