Diary

Diary

日々学んだことをアウトプットする場として初めてみました

xargs で並列処理

xargs では -P オプションを使うことで並列処理させることが可能です。

# -P2 の 2 の数は何個並列で走らせるかを表す
$ ... | xargs -P2

[目次]

最大実行数の確認

論理 CPU の数は、以下のいずれかの方法で取得可能です。

# 以下ディレクトリのファイルの中身を見てプロセッサの数を確認 (linux)。
$ cat /proc/cpuinfo | grep processor | wc -l
4

# 以下の変数でも確認が可能。
$ echo $(nproc)
4

xargs にそのままぶち込むことも可能です。

# 全ての .png ファイルを、convert を使って .jpg に変換する例。
$ ls *.png | sed 's/\.png//' | xargs -P$(nproc) -I@ convert @.png @.jpg

実験

マルチプロセスとして複数同時に処理されていることを確認します。

# -P フラグなし
## 1 + 2 + 3 = 6 秒かかる
$ time seq 3 | xargs -I@ sleep @
real    0m6.036s
user    0m0.001s
sys     0m0.044s

# -P フラグあり
## 並列に実行されていることがわかる。
## max(1 + 2 + 3) = 3 秒かかる。
$ time seq 3 | xargs -P3 -I@ sleep @
real    0m3.025s
user    0m0.009s
sys     0m0.030s

並列処理されてること

以下のような計算をさせることで、実は並列実行されていることがわかります。

# CPU に負荷をかける処理。
$ time echo -e '1\n2\n3' | xargs -I{} -P 3 bash -c 'for i in {0..100000}; do sum=$(($sum + $i)); done'

real    0m1.420s
user    0m3.944s
sys     0m0.199s

論理 CPU を超えた場合

# CPU を消費しない処理はそのまま実行される。
$ time echo -e '1\n2\n3\n1\n2\n3\n1\n2\n3\n1\n2\n3' | xargs -I{} -P 12 sleep {}

real    0m3.075s
user    0m0.008s
sys     0m0.101s

# CPU を消費する計算は論理 CPU の数までしかスケールしない。
## 論理 CPU ギリギリの時は、ほとんど実時間は変わらない。
$ time echo -e '1\n2\n3\n1' | xargs -I{} -P 4 bash -c 'for i in {0..100000}; do sum=$(($sum + $i)); done'

real    0m1.521s
user    0m4.981s
sys     0m0.267s

## 12 プロセス走らせた場合。
$ time echo -e '1\n2\n3\n1\n2\n3\n1\n2\n3\n1\n2\n3\n' | xargs -I{} -P 12 bash -c 'for i in {0..100000}; do sum=$(($sum + $i)); done'

real    0m4.292s
user    0m14.312s
sys     0m0.964s

おわりに

linux で並行で処理を使う機会はそうそうないかと思いますが、積極的に探して使っていきたいと思いました。

また、linux には他にも並行処理を実現する手段として、parallelコマンドなども有名なようです。こちらも機会があればふれてみたいと思います。