コマンドを並列実行したい時があります。
たとえば、たくさんの画像を変換したり、動画を変化したりなどジョブを大量に起動することをしたいとき
コマンド実行中もマルチコアのCPUが余っててもったいなーって思います。i7などは4コア2スレッドの8CPU有りますからね。
またruby などはGIL ( global interpreter lock )で上限ストップがかかってたり。
普段は xargs
並列実行は xargs を使ってます。
find | xargs -P0
GNU parallel というものを見つけた
GNU Parallel を使うと並列実行が可能になるということを知りました。
早速インストール
brew install parallel sudo apt install parallel
prallel の特徴
- 並列実行したいコマンドと並列実行したいファイルを引数を指定する。
- パイプライン処理に埋め込む
- sshlogin で複数マシンに流せる。
などのようです。
早速使ってみる
parallel echo {}::: a b c
100回実行してみる。
parallel echo $1 ::: {001..100}
基本コマンドはカンタン
paralell 実行したいコマンド {} ::: @{コマンドに渡したい引数一覧}
では画像処理をする場合
parallel convert {} {.}png ::: *.jpg
なるほど楽ですね。でもコレって速いのかな。
同じマシン上ならまず効果がないことわかった。
ナニも指定してないとき
takuya@test$ time find -name '*jpg' -exec convert {} {}.png \; real 0m3.493s user 0m2.751s sys 0m0.565s
parallel実行時
takuya@test$ time parallel -j 8 convert {} {}.png ::: *.jpg real 0m1.866s user 0m4.303s sys 0m1.467s
xargs の並列実行オプション
takuya@test$ time find -name '*jpg' | xargs -I@ -P0 convert @ @.png real 0m1.415s user 0m3.702s sys 0m0.939s
あんまり早くない。
予想だけど、parallel がシェルを起動してその後にコマンドを実行するためにオーバーヘッドがたぶん大きいのだと思う。
ということは 通常処理なら xargs が最速。
parallel の使い道はあるの?
ある。
ssh 経由での実行
ssh 経由で実行できる。
ssh 経由の実行先にもparallel をインストールを入れる必要がある。
takuya@:~$ parallel -S 10.0.2.127 echo {} ::: a b c a b c
ssh で複数のサーバーに分散させれば、このコマンドは便利だと思う。
ただ、ssh のコネクションの開始に時間がかかるので、1ジョブが数分以上かかるなら特に効果が見込めるんじゃないかな。