我正在编写一个小脚本,在几百个PNG文件上调用“PNGOUT”工具。我只是这样做了:
find $BASEDIR -iname "*png" -exec pngout {} \;
然后我看着我的CPU显示器,注意到只使用了一个核心,这很可悲。
在双核,四核,八核和六核(?)核心桌面的这个时代,我如何简单地将此任务与Bash并行化? (这不是我第一次有这样的需求,因为很多这些工具都是单线程的......我已经有了mp3编码器的情况。)
只需在后台运行所有 pngout 吗?我的发现命令会如何? (我不太确定如何混合查找和'&'字符)
如果我有三百张图片,这意味着要在三百个流程之间进行交换,这看起来不太好!?
或者我应该在“nb dirs”中复制我的三百个文件,其中“nb dirs”将是核心数量,然后同时运行“nb发现”? (这将足够接近)
但我该怎么做?
答案 0 :(得分:22)
回答我自己的问题......事实证明 xargs 命令的一个相对未知的功能可以用来完成它:
find . -iname "*png" -print0 | xargs -0 --max-procs=4 -n 1 pngout
Bingo,在四核机器上即时加速4倍:)
答案 1 :(得分:4)
在后台生成所有任务:
find $BASEDIR -iname "*png" | while read f; do
pngout "$f" &
done
但当然这不是最好的选择。一次做'n'个任务:
i=0
find $BASEDIR -iname "*png" | while read f; do
pngout "$f" &
i=$((i+1))
if [[ $i -gt $NTASKS ]]; then
wait
i=0
fi
done
它不是最佳的,因为它等待所有并发任务完成以启动另一个组;但它应该比没有好。
答案 2 :(得分:2)
Parallellization很少是微不足道的。在您的情况下,如果您可以在相同大小的集合中唯一地选择文件,那么您可以运行查找脚本的多个副本。您不想在后台启动300张照片。对于这样的工作,顺序运行它们通常会更快。背景命令或使用批处理都是可行的选择。
假设文件是连续编号的,你可以在一个查找中使用类似“ [0-4] .png”的查找模式,在另一个文件中使用“ [5-9] .png”。这将使两个核心运行大致相同的时间。
农业任务将涉及调度员 - 跑步者设置。构建,测试和运行这将花费很长时间。
启动BOINC以使用这些备用处理器。在监视cpu频率时,您可能希望忽略niced进程。将这样的代码添加到rc.local。
for CPU in /sys/devices/system/cpu/cpu[0-9]*; do echo 1 > ${CPU}/cpufreq/ondemand/ignore_nice_load done