-j -N을 사용한 GNU 병렬은 여전히 ​​하나의 CPU를 사용합니다.

-j -N을 사용한 GNU 병렬은 여전히 ​​하나의 CPU를 사용합니다.

리소스를 포화시키지 않고 멀티 코어 노드에서 합리적인 병렬화를 얻는 방법은 무엇입니까? 다른 많은 유사한 질문과 마찬가지로, 문제는 합리적인 성능을 위해 GNU Parallel을 조정하는 방법을 배우는 방법입니다.

아래 예에서는 리소스가 포화되지 않고 프로세스를 병렬로 실행할 수 없거나 -j -N특정 옵션을 사용한 후 모든 것이 하나의 CPU에서 실행되는 것처럼 보입니다.

멀티 코어 시스템에서 실행되는 Bash 스크립트 내부에서 다음 루프가 GNU Parallel로 전달됩니다.

for BAND in $(seq 1 "$BANDS") ;do
        echo "gdalmerge_and_clean $VARIABLE $YEAR $BAND $OUTPUT_PIXEL_SIZE_X $OUTPUT_PIXEL_SIZE_Y"
done |parallel

그러나 이로 인해 기계가 포화되어 처리 속도가 느려질 수 있습니다.

man parallel내가 읽은 후에

--작업 -N
-j -N
--max-procs -N
-P -N

CPU 스레드 수에서 N을 뺀 수입니다.

너무 많은 작업을 병렬로 실행하세요. 평가된 숫자가 1보다 작으면 1이 사용됩니다.

참조: --스레드 수 --코어 수 --소켓 수

나는 사용해 보았습니다.

|parallel -j -3

그러나 어떤 이유로 이는 40개의 CPU 중 하나만 사용합니다. [h]top 검사를 사용하면 CPU 하나만 높은 사용량으로 보고되고 나머지는 0으로 떨어집니다. "CPU 수"는 사용하면 안 됩니다 -j -3. 예를 들어 3이면 CPU가 37개가 됩니다.

그러다가 아까 통화를 연장했어

-j -3 --use-cores-instead-of-threads

맹목적으로 하는 것 같아요. 나는 읽었다https://unix.stackexchange.com/a/114678/13011, 그리고 이러한 병렬 작업을 실행하는 데 사용하고 있는 클러스터의 관리자로부터 배웠습니다.하이퍼스레딩이 비활성화되었습니다.. 이것은 여전히 ​​​​CPU에서 실행됩니다.

이제 다음을 사용하려고 합니다.

for BAND in $(seq 1 "$BANDS") ;do
        echo "gdalmerge_and_clean $VARIABLE $YEAR $BAND $OUTPUT_PIXEL_SIZE_X $OUTPUT_PIXEL_SIZE_Y"
done |parallel -j 95%

또는 |parallel -j 95% --use-cores-instead-of-threads.

노트

참고로 이는 HTCondor를 통해 예약된 일괄 작업의 일부이며 각 작업은 약 40개의 사용 가능한 물리적 CPU가 있는 별도의 노드에서 실행됩니다.

위에서는 필요한 부분만 유지했습니다. 파이프된 전체 for 루프는 parallel다음과 같습니다.

for BAND in $(seq 1 "$BANDS") ;do
   # Do not extract, unscale and merge if the scaled map exists already!
   SCALED_MAP="era5_and_land_${VARIABLE}_${YEAR}_band_${BAND}_merged_scaled.nc"
   MERGED_MAP="era5_and_land_${VARIABLE}_${YEAR}_band_${BAND}_merged.nc"
   if [ ! -f "${SCALED_MAP+set}" ] ;then
       echo "log $LOG_FILE Action=Merge, Output=$MERGED_MAP, Pixel >size=$OUTPUT_PIXEL_SIZE_X $OUTPUT_PIXEL_SIZE_Y, Timestamp=$(timestamp)"
       echo "gdalmerge_and_clean $VARIABLE $YEAR $BAND $OUTPUT_PIXEL_SIZE_X >$OUTPUT_PIXEL_SIZE_Y"
   else
       echo "warning "Scaled map "$SCALED_MAP" exists already! Skipping merging.-""
   fi
done |parallel -j 95%
log "$LOG_FILE" "Action=Merge, End=$(timestamp)"
where `log` and `warning` are a custom functions

답변1

디버깅하려면 먼저 than 을 사용하는 것이 좋습니다 gdalmerge_and_clean.

노력하다:

seq 100 | parallel 'seq {} 100000000 | gzip | wc -c'

각 CPU 스레드가 하나의 작업을 올바르게 실행하고 있습니까?

seq 100 | parallel -j 95% 'seq {} 100000000 | gzip | wc -c'

20개의 CPU 스레드마다 19개의 작업을 올바르게 실행합니까?

내 생각엔 gdalmerge_and_clean실제로는 올바른 수의 인스턴스에서 실행되고 있지만 I/O에 따라 다르며 이를 기다리고 있는 것 같습니다. 따라서 CPU가 유휴 상태이고 기다리는 동안 디스크나 네트워크는 최대치에 도달합니다.

를 사용하여 올바른 수의 복제본이 시작되었는지 확인할 수 있습니다 ps aux | grep gdalmerge_and_clean.

디스크가 사용 중인지 확인할 수 있습니다 iostats -dkx 1.

관련 정보