GNU Parallel 与 -j -N 仍然使用一个 CPU

GNU Parallel 与 -j -N 仍然使用一个 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我读到

--jobs -N
-j -N
--max-procs -N
-P -N

CPU 线程数减去 N。

并行运行这么多作业。如果评估的数字小于 1,则将使用 1。

另请参阅:--线程数--核心数--套接字数

我尝试过使用

|parallel -j -3

但由于某种原因,这仅使用了 40 个 CPU 中的一个。通过 [h]top 检查,只有一个 CPU 被报告为高使用率,其余的降至 0。不应-j -3使用“CPU 数量”- 3,这会导致例如 37 个 CPU?

然后我延长了之前的通话时间

-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

要调试它,我建议您首先使用比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.

相关内容