Oli*_*ier 1 parallel-processing bash image-processing scientific-computing
我目前有一个非常大的目录,包含超过9000个文件夹,每个文件夹中包含jpeg图像(平均每个文件夹40个).
我的程序获取图像的输入文件夹,并将该文件夹中图像的特征向量输出到文本文件:
./process_image images/ output/
Run Code Online (Sandbox Code Playgroud)
我还有一个脚本,其用法如下:
./script.sh dirlist.txt images/ output/ 1
Run Code Online (Sandbox Code Playgroud)
第一个输入dirlist.txt包含输入目录中的文件夹名称.第二个和第三个输入是输入和输出的基本目录.第四个参数是我想要访问的dirlist中的条目的索引
假设imageset1在dirlist.txt中的索引1处,上面的示例将调用:
./process_image images/imageset1/ output/imageset1/
Run Code Online (Sandbox Code Playgroud)
如果我按顺序执行此操作,则需要几天的时间来处理所有9000个文件夹.在这种情况下,最好的并行化方法是什么?我应该编写一个脚本,将9000个文件夹分成块并分别运行脚本,每个脚本运行一定范围的索引吗?另外,如果一个可执行文件在RAM中的范围从100 MB到1 GB,我该如何确定我可以运行多少个程序?我有32 GB的RAM.
我每天定期处理65,000多张图像,而且我总是使用GNU Parallel - 请看这里和这里.我不打扰并行化C代码!
它允许您指定并行运行的作业数,或者只使用每个CPU核心一个作业的默认值.它使用起来非常简单.所有你要做的就是改变你的script.sh所以不是开始工作,而只是回应它本来会开始的所有命令,每行一个stdout,然后把它输入parallel,就像这样
script.sh | parallel
Run Code Online (Sandbox Code Playgroud)
您可以添加标记,例如-j 8并行运行8个作业,或者-k保持输出顺序(如果相关).
script.sh | parallel -j 8 -k
Run Code Online (Sandbox Code Playgroud)
同样,如果您担心内存使用情况,您可以告诉parallel只在系统具有至少1GB可用内存时才启动新作业:
script.sh | parallel --memfree 1G
Run Code Online (Sandbox Code Playgroud)
您还可以添加其他计算机的列表,它将为您分配作业:-)
这是一个很小的例子:
#!/bin/bash
# script.sh
for i in {0..99}; do
echo "echo Start job $i; sleep 5; echo End job $i"
done
Run Code Online (Sandbox Code Playgroud)
然后
script.sh | parallel
Run Code Online (Sandbox Code Playgroud)
在我的8核机器上,500秒的工作在70秒内完成,如果我使用,则在21秒内完成parallel -j 25.