我有一个大型数据集(>200k 文件),我想处理(将文件转换为另一种格式)。该算法大多是单线程的,因此很自然地使用并行处理。然而,我想做一件不寻常的事情。每个文件都可以使用两种方法之一(基于 CPU 和 GPU)进行转换,我想同时使用 CPU 和 GPU。
从抽象的角度讲,我有两个不同的命令(foo
和bar
),它们应该产生相同的结果。我想组织两个具有固定容量的线程池,分别运行最多 N 个实例foo
和 M 个实例bar
,并使用其中一个池处理每个输入文件,具体取决于哪个池有空闲插槽(不需要或不需要确定性)。
是否可以在 GNU 并行或任何其他工具中执行类似的操作?
答案1
像这样的东西:
gpus=2
find files |
parallel -j +$gpus '{= $_ = slot() > '$gpus' ? "foo" : "bar" =}' {}
不那么可怕:
parallel -j +$gpus '{=
if(slot() > '$gpus') {
$_ = "foo"
} else {
$_ = "bar"
}
=}' {}
-j +$gpus
每个 CPU 线程 + $gpus 运行一项作业
{= ... =}
使用perl代码设置$_。
slot()
作业槽号(1..cpu_threads+$gpus)。
答案2
#!/usr/bin/env bash
values=( a b c d e f g h i j k l m n o p q r s t u v w x y z)
start=0
function foo()
{
sleep 4
echo "foo ${1}"
}
function bar()
{
sleep 4
echo "bar ${1}"
}
function baz()
{
sleep 4
echo "baz ${1}"
}
while [ ${#values[@]} -gt 0 ]
do
if [ ${#values[@]} -gt 0 ]
then
foo "${values[0]}" &
values=("${values[@]:1}")
fi
if [ ${#values[@]} -gt 0 ]
then
bar "${values[0]}" &
values=("${values[@]:1}")
fi
if [ ${#values[@]} -gt 0 ]
then
baz "${values[0]}" &
values=("${values[@]:1}")
fi
wait
done
values=( a b c d e f g h i j k l m n o p q r s t u v w x y z)
您可以替换的值values=$(ls -1)