GNU parallel teilt die Arbeit nicht gleichmäßig auf

340
Zoltan

Nach meinem Verständnis sollte die Option -X die Argumente gleichmäßig auf die Jobs verteilen. Ich bekomme jedoch eine sehr verdrehte Verteilung:

user@host:/tmp/ptest$ count() { > echo $# > } user@host:/tmp/ptest$ export -f count  user@host:/tmp/ptest$ count *.jpg 5825 user@host:/tmp/ptest$ parallel -X count ::: *.jpg 5039 197 197 197 195 

Interessanterweise führt die Verwendung nur einer Teilmenge der Dateien zu einer gleichmäßigen Verteilung der Parameter:

user@host:/tmp/ptest$ count p129*.jpg 975 user@host:/tmp/ptest$ parallel -X count ::: p129*.jpg 244 244 244 243  user@host:/tmp/ptest$ count p12*.jpg 4007 user@host:/tmp/ptest$ parallel -X count ::: p12*.jpg 1002 1002 1002 1001  user@host:/tmp/ptest$ count p13*.jpg 1818 user@host:/tmp/ptest$ parallel -X count ::: p13*.jpg 455 455 455 453 

Warum ist der erste Fall falsch und wie kann ich ihn beheben?

2

1 Antwort auf die Frage

3
Ole Tange

-X verteilt sich gleichmäßig, wenn es auf EOF trifft.

In Ihrem Fall füllt es also den Puffer für eine vollständige Befehlszeile (5039 Namen) und startet diesen. Dann liest es weitere 800 Namen, bis es EOF erreicht. Das reicht nicht aus, um einen vollen Job zu beginnen, so dass diese auf die Jobslots verteilt werden.

Siehe Seite 37 https://zenodo.org/record/1146014

Auf diese Weise wird vermieden, dass alle Jobs vorab gelesen werden müssen, da möglicherweise nicht alle Jobs verfügbar sind (denken Sie tail -f file.names | parallel ...).

Es ist möglicherweise eine bessere Idee, wenn GNU Parallel genug Namen gelesen hat, um alle Jobslots zu füllen, bevor der nächste Job im -XModus gestartet wird, sodass EOF früher erkannt werden kann . Dies wurde jedoch nicht implementiert. Patch willkommen.

Eine Problemumgehung ist zu verwenden:

ls *.jpg | parallel --round --pipe -N1 parallel -Xj1 count 

Es kann nicht nach jedem Job ausgegeben werden, aber es kann eine Linebuffer-Ausgabe erfolgen:

ls *.jpg | parallel --lb --round --pipe -N1 parallel --lb -Xj1 count 

Wenn die Dateinamen \ n enthalten:

printf '%s\0' *.jpg | parallel --recend '\0' --round --lb --pipe -N1 parallel -0Xj1 count 
Vielen Dank für die Erklärung, warum dies passiert. Gibt es eine Möglichkeit, das gewünschte Verhalten zu erreichen oder anzunähern? Zoltan vor 5 Jahren 0
Das verlinkte Material sieht übrigens aus wie ein tolles Buch! Zoltan vor 5 Jahren 1