2013-05-16 16 views
7

Mam pętli while w bash obsługiwane tak:parallelizing pętli while z tablicami odczytanych z pliku w bash

while IFS=$'\t' read -r -a line; 
do 
    myprogram ${line[0]} ${line[1]} ${line[0]}_vs_${line[1]}.result; 
done < fileinput 

Odczytuje z pliku z tej struktury, dla odniesienia:

foo bar 
baz foobar 

i tak dalej (rozdzielane tabulatorami).

Chciałbym zrównoleglić tę pętlę (ponieważ wpisy są dużo i przetwarzanie może być wolne) za pomocą GNU równolegle, jednak przykłady nie są jasne, w jaki sposób przypisać każdej linii do tablicy, tak jak robię tutaj.

Jakie byłoby możliwe rozwiązanie (alternatywy dla pracy równoległej GNU)?

Odpowiedz

3

parallel nie jest to bezwzględnie konieczne tutaj; po prostu uruchom wszystkie procesy w tle, a następnie zaczekaj na ich zakończenie. Tablica jest niepotrzebne, jak można dać read więcej niż jedną zmienną do wypełnienia:

while IFS=$'\t' read -r f1 f2; 
do 
    myprogram "$f1" "$f2" "${f1}_vs_${f2}.result" & 
done < fileinput 
wait 

ten ma rozpocząć pojedynczą pracę dla każdy pozycja na liście, podczas gdy parallel mogą ograniczyć liczbę miejsc pracy działa na pewnego razu. Możesz wykonać to samo w bash, ale jest to trudne.

+0

Czy można to zrobić z maksymalnym ograniczeniem procesu? W przeciwnym razie uruchomienie go na dużym wejściu wysadzi w powietrze - edytuj, nie martw się, zobacz odpowiedź Hubbitusa – nmr

3

Chciałbym hakera @chepner. I nie wydaje się tak trudne osiągnąć podobne zachowanie z ograniczeniem liczby równoległych egzekucji:

while IFS=$'\t' read -r f1 f2; 
do 
    myprogram "$f1" "$f2" "${f1}_vs_${f2}.result" & 

    # At most as number of CPU cores 
    [ $(jobs | wc -l) -ge $(nproc) ] && wait 
done < fileinput 

wait 

To ograniczenie egzekucji przy max liczby rdzeni procesora przedstawić na system. Możesz łatwo to zmienić, zastępując $(nproc) żądaną ilością.

W międzyczasie powinieneś zrozumieć, co to nie jest uczciwa dystrybucja. Tak więc nie rozpoczyna nowego wątku zaraz po zakończeniu. Zamiast tego po prostu zaczekaj na ukończenie wszystkich, po starcie maksymalnej kwoty. Tak więc sumaryczna przepustowość może być nieco mniejsza niż z równoległą. Szczególnie, jeśli czas działania twojego programu może się różnić w dużym zakresie. Jeśli czas spędzony na każdym wywołaniu jest prawie taki sam, to czas podsumowania również powinien być mniej więcej równoważny.