【问题标题】:parralelizing a part of a script shell并行化脚本外壳的一部分
【发布时间】:2019-04-01 23:52:22
【问题描述】:
#!/bin/bash
for tracelength in 10 20 50 100 ; do
    step=0.1
    short=0
    long=1
    for firstloop in {1..10}; do
        ratio=0
        for secondloop in {1..10} ; do
            for repeat in {1..20} ; do
               echo $tracelength $short $long $ratio >results.csv
               python3 main.py "$tracelength" "$short" "$long" "$ratio" > file.smt2                     
               /usr/bin/time /Users/Desktop/optimathsat-1.5.1-macos-64-bit/bin/optimathsat < file.smt2 > results.csv
            done
            ratio=$(echo "scale=10; $ratio + $step" | bc)
        done
        short=$(echo "scale=10; $short + $step" | bc)
        long=$(echo "scale=10; $long - $step" | bc)
    done
done

我想并行化内部循环(repeat)。

我已经安装了 GNU 并行,并且我知道一些基础知识,但是因为循环有多个命令,我不知道如何并行化它们。

我将循环的内容转移到另一个脚本,我猜这是要走的路,但我的 3 个命令需要使用变量(tracelengthratio、short, long) 并按照它们运行。任何想法如何将参数从脚本传递到下标。还是您对并行化有更好的了解?

我正在编辑问题,因为我使用了下面的答案,但现在我的执行时间总是 0.00,不管 file.smt2 有多大。

这是新版本的代码:

 #!/bin/bash
    doone() {
        tracelength="$1"
        short="$2"
        long="$3"
        ratio="$4"
        #echo "$tracelength $short $long $ratio" >> results.csv
        python3 main.py "$tracelength" "$short" "$long" "$ratio" >> file.smt2
        gtime -f "%U" /Users/Desktop/optimathsat-1.5.1-macos-64-bit/bin/optimathsat < file.smt2
    }
    export -f doone
    step=0.2
    parallel doone \
             ::: 200 300 \
             :::: <(seq 0 $step 0.5) \
             ::::+ <(seq 1 -$step 0.5) \
             :::: <(seq 0 $step 0.5) \
             ::: {1..5} &> results.csv

【问题讨论】:

  • 并行执行此脚本意味着您将在一定时间内生成 8000 个进程。这可能不会像你想要的那么快。您可以将重复循环内容放入一个函数中,并在 for 循环内的后台执行该函数。此外,您的 results.csv 和 file.smt2 可能会被弄乱,因为进程会在执行过程中将其写入,就像相关记录可能不会彼此相邻。
  • @Edvin 啊,我在一个有 200 个核心的服务器上执行这个,我想利用它,在这种情况下,results.csv 可能会出现问题,因为最后我的目标是计算所有结果的平均值。但是 file.smt2 肯定应该是有序的,我怎么得到呢?
  • 您的问题可能是您将文件file.smt2 用于并行运行的所有作业。它将被每个作业覆盖。在答案中,这是通过使用管道来避免的。

标签: shell gnu-parallel optimathsat


【解决方案1】:

在您的原始代码中,您一次又一次地覆盖results.csv。我认为这是一个错误,而您希望将其合并到一个大的 csv 文件中:

doone() {
    tracelength="$1"
    short="$2"
    long="$3"
    ratio="$4"
    echo "$tracelength $short $long $ratio"
    python3 main.py "$tracelength" "$short" "$long" "$ratio" |
        /usr/bin/time /Users/Desktop/optimathsat-1.5.1-macos-64-bit/bin/optimathsat
}
export -f doone
step=0.1
parallel doone \
         ::: 10 20 50 100 \
         :::: <(seq 0 $step 0.9) \
         ::::+ <(seq 1 -$step 0.1) \
         :::: <(seq 0 $step 0.9) \
         ::: {1..20} > results.csv

如果您希望每次运行一个 csvfile:

parallel --results outputdir/ doone \
         ::: 10 20 50 100 \
         :::: <(seq 0 $step 0.9) \
         ::::+ <(seq 1 -$step 0.1) \
         :::: <(seq 0 $step 0.9) \
         ::: {1..20}

如果您想要一个包含参数和运行时的 csv 文件,请使用:

parallel --results output.csv doone \
         ::: 10 20 50 100 \
         :::: <(seq 0 $step 0.9) \
         ::::+ <(seq 1 -$step 0.1) \
         :::: <(seq 0 $step 0.9) \
         ::: {1..20}

【讨论】:

  • 我已经使用了这个解决方案,它的工作原理是我不再收到警告。但无论 file.smt2 有多大,我的 results.csv 文件中的执行时间始终为 0.00
猜你喜欢
  • 1970-01-01
  • 2021-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多