다음 for 루프는 수천 개의 작업을 병렬로 실행합니다.
OSMSOURCE=europe-latest.o5m
for SHAPEFILE in URBAN_[A-Z]*[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 병렬 처리가 어떻게 수행되는지 이해하고 이를 사용할 가치가 있는지 확인하고 싶습니다.
답변1
음, GNU Parallel은 동일한 작업을 수행하며 사용하기도 쉽습니다. 장점은 컴퓨터의 CPU 코어 수를 관리하고 기본적으로 해당 수(*)보다 더 많은 작업을 수행하지 않는다는 것입니다.
귀하의 프로그램은 그렇지 않습니다. 수백 개의 파일이 있는 경우 .poly
수백 개의 작업을 생성하게 되는데 osmconvert
, 이는 최선의 경우 최적이 아닐 수 있으며 최악의 경우(리소스에 따라) 시스템이 무릎을 꿇게 될 수 있습니다.
귀하의 프로그램은 다음과 같습니다(테스트되지 않음):
OSMSOURCE=europe-latest.o5m
OSMBASENAME="$(echo "${OSMSOURCE%.o5m}" | tr - _)"
for SHAPEFILE in URBAN_[A-Z]*[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
(*) 자신만의 임계값을 지정할 수 있습니다. 다른 용도로 사용할 수 있도록 예비 CPU 코어를 보관할 수도 있습니다. 반면, I/O가 병목 현상을 일으키는 경우 기본값보다 높은 숫자를 제공해야 할 수도 있습니다.
답변2
다음을 수행할 수 있습니다.
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_[A-Z]*[0-9]/*.poly
주어진 경우 command too long
다음을 시도하십시오.
find URBAN_[A-Z]*[0-9] -name *.poly | parallel doit {//} {/}
또는:
find . | grep -E 'URBAN_[A-Z].*[0-9]/.*.poly$' | parallel doit {//} {/}
한 시간 동안 돌아다녀 보세요 man parallel_tutorial
. 귀하의 명령줄이 감사할 것입니다.
답변3
사용 가능한 답변과 소규모 데이터 세트를 기반으로 시간 제한에 따라 변환을 테스트합니다.
테스트 데이터 세트
ESRI 셰이프파일 디렉토리
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개 항목이 포함됩니다..모으다문서
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_[A-Z]*[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_[A-Z]*[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_[A-Z]*[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_[A-Z]*[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
그러나 이는 변환할 수천 개의 폴리곤 파일에 비하면 최소한의 테스트 세트일 뿐입니다. 게다가 이러한 파일은 원격 디렉터리에 있기 때문에 실제로 읽고 쓰는 속도가 느려집니다.
답변4
80코어 시스템의 타이밍
절대 경로와 파일 이름을 사용하세요.
for SHAPEFILE in URAU_RG_100K_2011_2014_[A-Z]*[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
GNU Parallel을 사용하여 3559개의 변환을 수행하는 데 걸리는 시간(초)
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
시스템 세부정보
이러한 프로세스는 Dockerized Ubuntu 16.04.2 LTS 내부에서 실행됩니다(참조:https://hub.docker.com/r/_/ubuntu/), 호스트는 CentOS 시스템(Linux 3.10.0-514.26.2.el7.x86_64 #1 SMP)입니다. 총 메모리는1056760752KB수량인텔(R) 제온(R) CPU E7-4820 v3 @ 1.90GHz프로세서 수는 80개입니다.