【问题标题】:Bash: Running the same program over multiple coresBash:在多个内核上运行相同的程序
【发布时间】:2013-03-11 16:24:12
【问题描述】:

我可以访问一台可以访问 10 个内核的机器——我想实际使用它们。我习惯在自己的机器上做的事情是这样的:

for f in *.fa; do
  myProgram (options) "./$f" "./$f.tmp"
done

我想要对 10 个文件执行此操作 - 我们称它们为 blah00.fa、blah01.fa、... blah09.fa。

这种方法的问题是 myProgram 一次只使用 1 个核心,而在多核机器上这样做我会一次使用 1 个核心 10 次,所以我不会使用我的机器发挥了最大的能力。

如何更改我的脚本,使其同时运行我的所有 10 个 .fa 文件?我查看了Run a looped process in bash across multiple cores,但我无法从中获取命令来执行我想要的操作。

【问题讨论】:

  • 你试过gnu parallel?什么不适合你?
  • 您是否尝试过在该答案中使用 gnu 并行建议?
  • seq 0 10 | parallel myProgram -opt1 -opt2 ./blah{}.fa ./blah{}.tmp
  • 是的,我尝试使用并行。问题:在有许多内核的机器上,它没有安装,我没有 sudo 访问权限,所以不能并行使用。 :(
  • 您无需root即可安装;下载源代码并运行./configure --prefix=${HOME}; make; make install 将其安装在您的主目录中。

标签: linux bash parallel-processing multiprocessing


【解决方案1】:

你可以使用

for f in *.fa; do
    myProgram (options) "./$f" "./$f.tmp" &
done
wait

这将并行启动所有工作,然后等到它们全部完成后再继续。如果您的作业多于核心,您将启动所有作业并让您的操作系统调度程序担心进程的交换。

一种修改是一次启动 10 个作业

count=0
for f in *.fa; do
    myProgram (options) "./$f" "./$f.tmp" &
    (( count ++ ))        
    if (( count = 10 )); then
        wait
        count=0
    fi
done

但这不如使用parallel,因为您无法在旧作业完成时开始新作业,而且您也无法在开始 10 个作业之前检测旧作业是否已完成。 wait 允许您等待单个特定进程或所有后台进程,但不会让您知道任意一组后台进程中的任何一个何时完成。

【讨论】:

  • 下一个版本的 Bash 将有一个选项 (wait -n)。目前您可以执行this 之类的操作,但由于一些错误也将在下一个版本中修复,因此这有点过分。
【解决方案2】:

使用 GNU Parallel,您可以:

parallel myProgram (options) {} {.}.tmp ::: *.fa

发件人:http://git.savannah.gnu.org/cgit/parallel.git/tree/README

= 完整安装 =

GNU Parallel 的完整安装非常简单:

./configure && make && make install

如果您不是 root,您可以将 ~/bin 添加到您的路径并安装在 ~/bin 和 ~/share:

./configure --prefix=$HOME && make && make install

或者,如果您的系统缺少“make”,您可以简单地复制 src/parallel src/sem src/niceload src/sql 到你路径中的一个目录。

= 最小安装 =

如果您只需要并行并且没有安装“make”(也许 旧系统或 Microsoft Windows):

wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
chmod 755 parallel
cp parallel sem
mv parallel sem dir-in-your-$PATH/bin/

观看介绍视频以了解更多信息:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

【讨论】:

    【解决方案3】:
    # Wait while instance count less than $3, run additional instance and exit
    function runParallel () {
        cmd=$1
        args=$2
        number=$3
        currNumber="1024"
        while true ; do
            currNumber=`ps -e | grep -v "grep" | grep " $1$" | wc -l`
            if [ $currNumber -lt $number ] ; then
                break
            fi
            sleep 1
        done
        echo "run: $cmd $args"
        $cmd $args &
    }
    
    loop=0
    # We will run 12 sleep commands for 10 seconds each 
    # and only five of them will work simultaneously
    while [ $loop -ne 12 ] ; do
        runParallel "sleep" 10 5
        loop=`expr $loop + 1`
    done
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多