我在Bash中有一个while循环处理如下:
while IFS=$'\t' read -r -a line;
do
myprogram ${line[0]} ${line[1]} ${line[0]}_vs_${line[1]}.result;
done < fileinput
它从具有此结构的文件中读取,以供参考:
foo bar
baz foobar
依此类推(制表符分隔)。
我想使用GNU并行来并行化这个循环(因为条目很多并且处理速度很慢),但是我不知道如何将每一行分配给数组,就像我在这里一样。 / p>
什么是可能的解决方案(GNU并行工作的替代方案)?
答案 0 :(得分:9)
来自https://www.gnu.org/software/parallel/man.html#EXAMPLE:-Use-a-table-as-input:
“”“
table_file.tsv的内容:
foo<TAB>bar
baz <TAB> quux
运行:
cmd -o bar -i foo
cmd -o quux -i baz
你可以跑:
parallel -a table_file.tsv --colsep '\t' cmd -o {2} -i {1}
“”“
所以在你的情况下它将是:
cat fileinput | parallel --colsep '\t' myprogram {1} {2} {1}_vs_{2}.result
答案 1 :(得分:5)
我想要@chepner黑客。 并且通过限制并行执行次数似乎没有那么棘手的完成类似的行为:
while IFS=$'\t' read -r f1 f2;
do
myprogram "$f1" "$f2" "${f1}_vs_${f2}.result" &
# At most as number of CPU cores
[ $( jobs | wc -l ) -ge $( nproc ) ] && wait
done < fileinput
wait
它限制执行系统上存在的最大CPU核心数。您可以通过将$( nproc )
替换为所需金额来轻松改变它。
同时你应该明白什么是不诚实的分配。因此,它不会在一个完成之后启动新线程。相反,它只是等待完成所有,在开始最大金额后。因此汇总吞吐量可能略低于并行吞吐量。特别是如果你的程序的运行时间可能在很大范围内变化。如果在每次调用上花费的时间几乎相同,那么汇总时间也应大致相等。
答案 2 :(得分:3)
parallel
在这里并不是绝对必要的;只需在后台启动所有进程,然后等待它们完成。数组也是不必要的,因为您可以为read
提供多个变量来填充:
while IFS=$'\t' read -r f1 f2;
do
myprogram "$f1" "$f2" "${f1}_vs_${f2}.result" &
done < fileinput
wait
这会为列表中的每个项启动单个作业,而parallel
可以限制一次运行的作业数。你可以在bash
中完成相同的工作,但这很棘手。