Intereting Posts
Как я могу перечислить содержимое архивного архива без его запуска? Ошибка запуска Cygwin Putty: невозможно определить графическое окружение Изменение ключевой фразы GPG неэффективно Цветной вывод из сценария Bash Проверка узкого места ввода-вывода Перезапуск Gnome 3 в Debian Wheezy? Перечислите любой файл, заканчивающийся на .in и соответствующий .out с помощью сценария оболочки Каковы последствия установки скорости передачи данных в терминале из пользовательского пространства? Где находится файл конфигурации по умолчанию для принтера по умолчанию? Установка двойной загрузочной среды Ubuntu 14.04.3 LTS и Windows 7 linux – показать изображение на консоли / X11 Что делает программу Linux совместимой / несовместимой? «Неожиданный конец файла», возвращенный из скрипта BASH Прошивка с открытым исходным кодом для чтения электронных книг Использование openvpn с несколькими серверами под systemd

Стоит ли использовать параллельные процессы вместо forking в цикле for?

Следующие для цикла работают тысячи рабочих мест параллельно

OSMSOURCE=europe-latest.o5m for SHAPEFILE in URBAN_[AZ]*[0-9] ;do cd $SHAPEFILE for POLYGON in *.poly ;do osmconvert --drop-version $OSMSOURCE -B=$POLYGON --out-o5m > $(basename $OSMSOURCE .o5m |tr "-" "_")_$(basename $POLYGON .poly).o5m & done cd .. done 

Я хочу узнать, как GNU-параллель выполняет и понимает, стоит ли ее использовать.

Ну, параллель GNU будет делать то же самое, и это довольно легко использовать. Его преимуществом является то, что он будет заботиться о количестве ядер процессора на вашем компьютере и по умолчанию он не будет выполнять больше заданий, чем это (*).

В вашей программе нет. Если у вас есть сотни файлов .poly , вы osmconvert сотни рабочих заданий osmconvert , которые в лучшем случае могут оказаться не оптимальными, а в худшем случае может привести к снижению вашей системы (это зависит от ваших ресурсов).

Ваша программа будет чем-то вроде (не проверена):

 OSMSOURCE=europe-latest.o5m OSMBASENAME="$(echo "${OSMSOURCE%.o5m}" | tr - _)" for SHAPEFILE in URBAN_[AZ]*[0-9]; do cd "$SHAPEFILE" for POLYGON in *.poly; do echo "cd '$SHAPEFILE'; osmconvert --drop-version '$OSMSOURCE' -B='$POLYGON' --out-o5m > '${OSMBASENAME}_${POLYGON%.poly}.o5m'" done cd .. done | parallel # You may want to add a -j option 

(*) Вы можете дать ему свой собственный порог. Вы можете захотеть сохранить несколько запасных ядер процессора для чего-то другого. С другой стороны, если «в / в» является узким местом, вы можете указать большее число, чем значение по умолчанию.

Вероятно, вы можете сделать что-то вроде:

 OSMSOURCE=europe-latest.o5m export OSMSOURCE doit() { cd "$1" POLYGON="$2" osmconvert --drop-version $OSMSOURCE -B=$POLYGON --out-o5m > $(basename $OSMSOURCE .o5m |tr "-" "_")_$(basename $POLYGON .poly).o5m } export -f doit 

Теперь вы можете проверить, что это работает вручную:

 doit URBAN_dir file_in_URBAN_dir.poly 

Когда это работает:

 parallel doit {//} {/} ::: URBAN_[AZ]*[0-9]/*.poly 

Если это дает command too long , попробуйте:

 find URBAN_[AZ]*[0-9] -name *.poly | parallel doit {//} {/} 

Или:

 find . | grep -E 'URBAN_[AZ].*[0-9]/.*.poly$' | parallel doit {//} {/} 

Проведите час, пройдя через man parallel_tutorial . Ваша команда поблагодарит вас за это.

Сроки проверки конверсий на основе доступных ответов и небольшого набора данных.

Набор тестовых данных

Каталоги ESRI Shapefiles

 URAU_RG_100K_2011_2014_AT001L2 URAU_RG_100K_2011_2014_AT002L2 URAU_RG_100K_2011_2014_AT003L2 URAU_RG_100K_2011_2014_AT004L2 URAU_RG_100K_2011_2014_AT005L2 URAU_RG_100K_2011_2014_AT006L1 URAU_RG_100K_2011_2014_UK546L0 

которые включают следующие 9 файлов .poly

 URAU_RG_100K_2011_2014_AT001L2/URAU_RG_100K_2011_2014_AT001L2_0.poly URAU_RG_100K_2011_2014_AT002L2/URAU_RG_100K_2011_2014_AT002L2_0.poly URAU_RG_100K_2011_2014_AT003L2/URAU_RG_100K_2011_2014_AT003L2_0.poly URAU_RG_100K_2011_2014_AT004L2/URAU_RG_100K_2011_2014_AT004L2_0.poly URAU_RG_100K_2011_2014_AT005L2/URAU_RG_100K_2011_2014_AT005L2_0.poly URAU_RG_100K_2011_2014_AT006L1/URAU_RG_100K_2011_2014_AT006L1_0.poly URAU_RG_100K_2011_2014_UK546L0/URAU_RG_100K_2011_2014_UK546L0_0.poly URAU_RG_100K_2011_2014_UK546L0/URAU_RG_100K_2011_2014_UK546L0_1.poly URAU_RG_100K_2011_2014_UK546L0/URAU_RG_100K_2011_2014_UK546L0_2.poly 

будет запускать 9 рабочих мест параллельно

Ветвление

 for SHAPEFILE in URAU_RG_100K_2011_2014_[AZ]*[0-9]/ ;do cd $SHAPEFILE && for POLYGON in *.poly ;do time osmconvert --drop-version $OSMSOURCE -B=$POLYGON --out-o5m > $(basename $OSMSOURCE .o5m |tr "-" "_")_$(basename $POLYGON .poly).o5m & done && cd .. ;done 
 real 6m0.951s user 5m36.869s sys 0m20.298s real 6m23.591s user 5m43.808s sys 0m20.336s real 6m24.066s user 5m44.619s sys 0m19.936s real 6m24.129s user 5m45.239s sys 0m19.378s real 6m29.208s user 5m43.094s sys 0m19.314s real 6m30.974s user 5m44.318s sys 0m19.870s real 6m33.625s user 5m45.233s sys 0m19.658s real 6m33.731s user 5m45.712s sys 0m20.001s real 6m41.014s user 6m15.112s sys 0m19.571s 

Параллельно с GNU

 for SHAPEFILE in URAU_RG_100K_2011_2014_[AZ]*[0-9]*/ ;do cd "$SHAPEFILE"; for POLYGON in *.poly ;do echo "cd '$SHAPEFILE'; time osmconvert --drop-version '$OSMSOURCE' -B='$POLYGON' --out-o5m > $(basename $OSMSOURCE .o5m |tr "-" "_")_$(basename $POLYGON .poly).o5m"; done; cd ..; done |parallel -j 10 
 real 6m19.005s user 5m42.739s sys 0m18.798s real 6m26.939s user 5m44.689s sys 0m19.257s real 6m27.152s user 5m44.597s sys 0m19.644s real 6m28.821s user 5m41.650s sys 0m18.283s real 6m38.174s user 5m44.367s sys 0m19.564s real 6m40.277s user 5m45.000s sys 0m19.650s real 6m39.940s user 5m45.421s sys 0m19.208s real 6m40.285s user 5m45.443s sys 0m19.393s real 6m40.428s user 5m48.828s sys 0m18.871s 

Использование абсолютных путей и имен файлов

 for SHAPEFILE in URAU_RG_100K_2011_2014_[AZ]*[0-9]*/ ;do for POLYGON in $SHAPEFILE*.poly ;do echo "time osmconvert --drop-version --out-o5m $OSMSOURCE -B=$(readlink -f $POLYGON) > $(dirname `readlink -f $POLYGON`)/$(basename ${OSMSOURCE%.o5m})_$(basename ${POLYGON%.poly}).o5m" ;done ;done |parallel -j 10 
 real 6m6.919s user 5m39.203s sys 0m19.659s real 6m23.779s user 5m43.835s sys 0m19.225s real 6m26.033s user 5m45.370s sys 0m19.235s real 6m26.871s user 5m46.124s sys 0m19.780s real 6m33.355s user 5m41.902s sys 0m18.556s real 6m34.368s user 5m42.973s sys 0m19.156s real 6m37.063s user 5m46.169s sys 0m19.669s real 6m37.363s user 5m46.846s sys 0m19.194s real 6m37.428s user 5m49.679s sys 0m19.674s 

Определение функции оболочки

 OSMSOURCE=$(realpath europe-latest.o5m) export OSMSOURCE osmpolyclip() { cd "$1" POLYGON="$2" osmconvert --drop-version $OSMSOURCE -B=$POLYGON --out-o5m > $(basename $OSMSOURCE .o5m |tr "-" "_")_$(basename $POLYGON .poly).o5m } 

а также

 parallel time osmpolyclip {//} {/} ::: URAU_[AZ]*[0-9]/*.poly 
 real 6m19.749s user 5m41.909s sys 0m19.162s real 6m23.559s user 5m43.881s sys 0m18.748s real 6m34.149s user 5m41.859s sys 0m18.895s real 6m38.776s user 5m44.614s sys 0m18.767s real 6m38.817s user 5m44.420s sys 0m19.038s real 6m39.421s user 5m46.060s sys 0m18.819s real 6m39.889s user 5m45.917s sys 0m19.541s real 6m39.956s user 5m48.368s sys 0m19.742s real 6m51.397s user 6m26.095s sys 0m19.306s 

Это, однако, минимальный набор тестов, по сравнению с тысячами файлов Polygon, для выполнения задач для преобразования. Кроме того, файлы находятся в удаленном каталоге, который фактически замедляет чтение и запись.

Сроки в 80-ядерной системе

Используя абсолютный путь и имена файлов,

 for SHAPEFILE in URAU_RG_100K_2011_2014_[AZ]*[0-9]*/ ;do for POLYGON in $SHAPEFILE*.poly ;do echo "time osmconvert --drop-version --out-o5m $OSMSOURCE -B=$(readlink -f $POLYGON) > $(dirname `readlink -f $POLYGON`)/$(basename ${OSMSOURCE%.o5m})_$(basename ${POLYGON%.poly}).o5m" ;done ;done |parallel -j 10 

тайминги для 3559 конверсий, в секундах, с использованием GNU Parallel, являются

  timings.real timings.user timings.sys Min. :387.4 Min. :367.5 Min. :17.95 1st Qu.:636.8 1st Qu.:616.3 1st Qu.:19.35 Median :639.4 Median :618.5 Median :19.74 Mean :637.6 Mean :616.8 Mean :19.81 3rd Qu.:642.5 3rd Qu.:621.5 3rd Qu.:20.15 Max. :709.3 Max. :689.9 Max. :27.34 

Подробная информация о системе

Процессы выполнялись изнутри докционированного Ubuntu 16.04.2 LTS (см. https://hub.docker.com/r/_/ubuntu/ ), а хост – это блок CentOS (Linux 3.10.0-514.26.2. el7.x86_64 # 1 SMP). Общая память составляет 1056760752 кБ, а число процессоров Intel (R) Xeon (R) E7-4820 v3 @ 1,90 ГГц – 80.