在 bash 中跨多个核心运行循环进程

问题描述 投票:0回答:3

我有一个包含以下循环的 shell 脚本。

i=0  
upperlimit=$verylargevariable  
do  
   complexstuff RunManager file $i  
   i= 'expr $i +1'  
done

此脚本在四核计算机上运行,根据

top
,在执行一次循环迭代时使用每个核心的大约 15%。我想将其分布在四个核心上,以便循环的每次迭代都会执行
complexstuff
四次,每个核心一次,这样资源将得到更有效的利用。我们正在讨论目前需要几个小时的计算,因此效率不仅仅是这里的良好实践。 (每次迭代的输出显然与前一次迭代无关。)

PS:主机是运行 Cent-OS 的服务器,如果有帮助的话。

bash centos parallel-processing
3个回答
11
投票

使用 GNU Parallel,您可以:

seq $verylargevariable | parallel -j150% complexstuff RunManager file

150% 将为每个核心运行 1.5 个进程,因此,如果当前使用 15%,这将为您在所有 4 个核心上提供大约 100% 的性能。

要了解更多信息,请观看介绍视频:http://www.youtube.com/watch?v=OpaiGYxkSuQ


3
投票

除了 Ole Tange 解决方案(看起来很棒),如果您的计算具有非常相似的持续时间,您可以尝试这样的方法:

i=0  
upperlimit=$verylargevariable  
do  
   complexstuff RunManager file $i &
   i= 'expr $i + 1'
   complexstuff RunManager file $i &
   i= 'expr $i + 1'
   complexstuff RunManager file $i &
   i= 'expr $i + 1'
   complexstuff RunManager file $i &
   i= 'expr $i + 1'
   wait
done

这样,在每次运行循环时,您将创建 4 个 bash 子进程来启动您的计算(并且由于系统很棒,它会将它们分派到不同的核心上)。如果有 4 个进程还不足以烧毁所有 cpu,请增加每个循环上创建的进程数。


0
投票

快速破解解决方案:只需不断启动作业,直到达到您想要同时运行的最大作业数。毫无疑问,有比下面这个示例更清晰的细节,但这是我针对类似问题整理的内容,并且它有效。 (“睡眠”命令的持续时间可能有点过长,但我的程序每个命令都需要几分钟才能运行,因此睡眠并不会过多)

#!/bin/bash -x
PAGE="check001"
#DEBUG="-d"
DEBUG=""
ls -1 tiles/${PAGE}/line???/*.png | sort | while read f ; do
    if [ -f `dirname $f`/`basename $f .png`.txt ] ; then
      :
    else
        JOBS="`ps auxww|fgrep ../../recogniser/chocr-check|grep -v fgrep|wc -l`"
        echo Before loop: JOBS = $JOBS
        while [ $JOBS -ge 4 ] ; do
            sleep 10
            JOBS="`ps auxww|fgrep ../../recogniser/chocr-check|grep -v fgrep|wc -l`"
        done
        ../../recogniser/chocr-check $DEBUG $f > `dirname $f`/`basename $f .png`.txt &
        sleep 2
    fi
done
© www.soinside.com 2019 - 2024. All rights reserved.