処理したい(ファイルを別の形式に変換する)大きなデータセット(> 200,000ファイル)があります。アルゴリズムはほとんどシングルスレッドなので、並列処理を使用するのは当然です。しかし、私は何か珍しいことをしたかったのです。各ファイルは2つの方法(CPUとGPUベース)のいずれかを使用して変換できますが、CPUとGPUの両方を使用したいと思います。
抽象的な意味で同じ結果を生成する2つの異なるコマンド(foo
および)があります。bar
固定容量を持つ2つのスレッドプールを構成し、それぞれ最大Nインスタンスfoo
とMインスタンスを実行し、プールのbar
1つを使用して利用可能なスロットを持つプールに応じて(性別を決定する必要がないか必要ありません)、各入力ファイルを処理します。しようとします。
GNU Parallelや他のツールで同様のことを行うことはできますか?
答え1
このような:
gpus=2
find files |
parallel -j +$gpus '{= $_ = slot() > '$gpus' ? "foo" : "bar" =}' {}
あまり怖くないです。
parallel -j +$gpus '{=
if(slot() > '$gpus') {
$_ = "foo"
} else {
$_ = "bar"
}
=}' {}
-j +$gpus
CPUスレッドごとに1つのジョブを実行+ $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)