![GNU Parallel 与 -j -N 仍然使用一个 CPU](https://linux22.com/image/213966/GNU%20Parallel%20%E4%B8%8E%20-j%20-N%20%E4%BB%8D%E7%84%B6%E4%BD%BF%E7%94%A8%E4%B8%80%E4%B8%AA%20CPU.png)
如何在多核节点上获得合理的并行化而不导致资源饱和?与许多其他类似问题一样,问题实际上是如何学习调整 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 -NCPU 线程数减去 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
.