并行化具有大量迭代的 for 循环

并行化具有大量迭代的 for 循环

我想并行化一个 for 循环,其中循环中的迭代次数可能非常大,例如 10^6。因此,如果我可以创建线程而不是进程,那就更好了。怎么做?代码如下

N=$1

for (( i=0; i < $N; i++ )); do

    ./random >> output /* in each iteration one random number is appended to
                          a file "output" */                                

done

答案1

  1. 您无法从 shell 中生成线程。
  2. 您不想从多个进程写入同一个文件。
  3. 如果你的random程序只是生成一个数字,
    • 它应该足够快,以便您的循环将受到 io 限制。
    • 如果可以的话,您应该编辑它以接受参数并打印那么多数字。
    • 如果实际执行是瓶颈,您应该重新考虑如何生成数字。也许将代码发布到代码审查

如果你真的真的还是想这样做,分块做:

for i in {0..9}; do
    for ((j = 1; j < $N/10; j++)); do
        ./random
    done > tmp$i &
    pid[$i]=$?
done
for i in {0..9}; do
    wait ${pid[$i]}
done
cat tmp{0..9} >> outfile

答案2

我不知道有任何 shell 允许您手动创建新线程,通常您只能利用当前 shell 中的现有线程(或创建子 shell,它们实际上是新进程)。使用python或其他语言代替。

即使可以,我也真的不建议使用 shell 脚本来完成这种规模的事情。与编译语言相比,运行 10^6 次迭代时性能损失可能很大。

答案3

一如既往,问题是资源争用。您需要限制同时运行的进程/线程的数量。

此外,是否拥有并发线程很大程度上取决于将执行的处理类型。如果有一个良好的编程组合:内存、cpu、i/o 等,那就更好了。如果所有子进程都将执行所有 cpu 操作,那么同时运行 10-20 个子进程不会加快任何速度。您可以尝试将处理工作外包给其他机器;例如,使用 ssh 在其他机器上启动调用并获取结果。

快速而肮脏的第一遍可能是这样的:

N=$1 # max number to iterate on
shift # rest of command line is the command to run: e.g. "./random"
maxcount=10 # maximum in the pool
curcount=0  # how many currently in the pool
reaper () {
    wait
    curcount=`expr $curcount - 1`
}
spawnnext () {
    n=$1
    shift
    while [ $curcount -ge $maxcount ]; do
        sleep 1 # wait for a free slot in the pool
    done
    echo $n
    "$@" &
    curcount=`expr $curcount + 1`
}

trap 'reaper' CHLD

for (( i=0; i < $N; i++)); do
    spawnnext $i "$@"
done

笔记;我还没有测试过这个;只是临时写下来的。

但我会用更高级、性能更好的语言(例如 Python)来完成此操作:https://stackoverflow.com/questions/3033952/python-thread-pool-similar-to-the-multiprocessing-pool

答案4

如果您的任务只是生成随机数:

perl -e 'for($t=0;$t<1000000;$t++) { print int(rand()*1000),"\n" }'

如果您的任务确实是其他任务,您可以使用 GNU Parallel:

parallel ./random :::: <(seq 1000000) > output

您可以简单地通过以下方式安装 GNU Parallel:

wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
chmod 755 parallel

观看介绍视频以了解更多信息:http://pi.dk/1

相关内容