Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
東海道らぐ名古屋オフ(2017.10.7)発表内容より
Linuxにて
複数のコマンドを並列実行
(同時実行数の制限付き)
H.Hiro
Website: https://hhiro.net/
Twitter: @h_hiro_
このスライドについて
• 2017.10.7の東海道らぐ名古屋オフ
https://tokaidolug.connpass.com/event/67522/
にて発表した内容を、スライド化・加筆修正したものです
• 東海道らぐ名古屋オフの
当日...
目的
• Linuxにて、複数のプログラムを並列実行したい。
• 各プログラムは1スレッドで動く前提とする。
• このとき、同時実行数を制限したい。
すなわち、同時実行数を制限するという条件のもとで
なるべく処理を早く終わらせたい。
きっかけ
• 私は研究の仕事をしていて、「パラメータを変えて複数の
状況で計算をさせる」という実験を行うことが多い。
そうなると、複数コアがあるマシンで並列で動かしたい。
# 例
./program 1 10
./program 1 100
....
結論
• 実はxargsでだいたいのことはできてしまう
• 複雑なことをしたければparallel(GNU parallel)を
使うという手もある
最初に知った方法(wait利用)
waitというコマンドを知り、これを使って工夫することを考えた。
※wait:&を付けてバックグラウンド実行したコマンドがすべて
終わるまで待つ
まず&について簡単な確認
sleep 3; sleep 2; s...
最初に知った方法(wait利用)
sleep 3 & sleep 2 & sleep 1; echo END
# これは、3秒待ってからENDが表示されるわけではない。
# 1秒しか待たない。
# 3秒待つのと2秒待つのはバックグラウンドなので...
最初に知った方法(wait利用)
プログラム例
running=0
for i in `seq 6 -1 1`; do # 6 5 4 3 2 1の順で実行
sleep $i
running=`expr $running + 1`
if [ $...
最初に知った方法(wait利用)
この方法の問題点:
並列実行したものが全部終わらないと、次へ進めない
先程の例はこんな時間の使い方
しかし実際は、こう詰められるはず
コア1
コア2
コア3
wait終了 wait終了
コア1
コア2
コア3
...
xargsを使う方法
xargsを使う方法
つい最近知った。参考記事:
• xargs を使ってカジュアルに並列処理 - たごもりすメモ
http://tagomoris.hatenablog.com/entry/20110513/1305267021
• xarg...
xargsを使う方法
• 普通、xargsは「標準入力から受け取った値を
コマンドの引数にまとめて渡す」。
seq 1 3 | xargs echo # "echo 1 2 3" と同等
• -Lオプションを付けると、標準入力から受け取った値を...
GNU parallelを使う方法
GNU parallelを使う方法
• さっきの記事で挙げられていて知った
• 参考記事
– コマンドを並列に実行するGNU parallelがとても便利
- りんごがでている
http://bicycle1885.hatenablog.com...
GNU parallelを使う方法
使い方
# -j 1 だとただの逐次実行
seq 4 3 10 | parallel -j 1 'echo sleep {} start;
sleep {}; echo sleep {} end: `date...
GNU parallelを使う方法
使い方
# -j 3 で3つすべてを並列に実行
seq 4 3 10 | parallel -j 3 'echo sleep {} start;
sleep {}; echo sleep {} end: `d...
GNU parallelを使う方法
使い方
# -j 2 だと、「4秒待つ」と「7秒待つ」のどちらか(=前者)が
# 終わってから、「10秒待つ」が実行される
seq 4 3 10 | parallel -j 2 'echo sleep {} ...
GNU parallelを使う方法
使い方
# 括弧やリダイレクトがそのまま書けるのもポイント高いところ
seq 4 3 10 | parallel -j 1 '(echo sleep {} start;
sleep {}; echo slee...
おまけ:
全プログラムをなるべく早く
終わらせるためのポイント
おまけ
• 終了までの時間を早くしたければ、基本的には「実行時間が
長いものから実行する」のがよい。
ただ、完全に最適な実行時間にしたければ、全組み合わせを
試すのに相当する程度の時間はかかる。
• 同時並列数を固定とした場合、
– (すべての...
Upcoming SlideShare
Loading in …5
×

Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)

1,403 views

Published on

東海道らぐ 2017.10.7 名古屋オフ https://tokaidolug.connpass.com/event/67522/ での発表内容より

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)

  1. 1. 東海道らぐ名古屋オフ(2017.10.7)発表内容より Linuxにて 複数のコマンドを並列実行 (同時実行数の制限付き) H.Hiro Website: https://hhiro.net/ Twitter: @h_hiro_
  2. 2. このスライドについて • 2017.10.7の東海道らぐ名古屋オフ https://tokaidolug.connpass.com/event/67522/ にて発表した内容を、スライド化・加筆修正したものです • 東海道らぐ名古屋オフの 当日その場で資料を 仕上げていて、スライドまで 作る余裕がなかったので (このネタで話す構想自体は あった)、当日はGoogle ドキュメントに書いた内容で 話してました
  3. 3. 目的 • Linuxにて、複数のプログラムを並列実行したい。 • 各プログラムは1スレッドで動く前提とする。 • このとき、同時実行数を制限したい。 すなわち、同時実行数を制限するという条件のもとで なるべく処理を早く終わらせたい。
  4. 4. きっかけ • 私は研究の仕事をしていて、「パラメータを変えて複数の 状況で計算をさせる」という実験を行うことが多い。 そうなると、複数コアがあるマシンで並列で動かしたい。 # 例 ./program 1 10 ./program 1 100 ./program 2 10 ./program 2 100 : • 以前は、マシンのコア数に応じて手作業で 実験パターン数を分け、そのスクリプトを作っていたのだが、 流石に面倒になってきて、自動化しようと決心したのであった。
  5. 5. 結論 • 実はxargsでだいたいのことはできてしまう • 複雑なことをしたければparallel(GNU parallel)を 使うという手もある
  6. 6. 最初に知った方法(wait利用) waitというコマンドを知り、これを使って工夫することを考えた。 ※wait:&を付けてバックグラウンド実行したコマンドがすべて 終わるまで待つ まず&について簡単な確認 sleep 3; sleep 2; sleep 1 # ↑これだと逐次実行なので6秒待つ sleep 3 & sleep 2 & sleep 1 & # 後ろに&が付いているコマンドはバックグラウンド実行。 # この場合、何も待たない(実際には、待つということは # 行われるがそれがバックグラウンドなので何の影響もない)
  7. 7. 最初に知った方法(wait利用) sleep 3 & sleep 2 & sleep 1; echo END # これは、3秒待ってからENDが表示されるわけではない。 # 1秒しか待たない。 # 3秒待つのと2秒待つのはバックグラウンドなので。 sleep 3 & sleep 2 & sleep 1 & wait; echo END # これだと、3秒待ってからENDが表示される。 これを使い、「コマンド実行回数をカウントし、所定の回数 コマンドを実行したら、全部終わるまでwaitする」ということを していた。
  8. 8. 最初に知った方法(wait利用) プログラム例 running=0 for i in `seq 6 -1 1`; do # 6 5 4 3 2 1の順で実行 sleep $i running=`expr $running + 1` if [ $running -ge 3 ]; then running=0 wait fi done この場合、待つのは 6+5+…+1=21秒 ではなく、 6+3=9秒である。 6と5と4は並列、 3と2と1も並列。
  9. 9. 最初に知った方法(wait利用) この方法の問題点: 並列実行したものが全部終わらないと、次へ進めない 先程の例はこんな時間の使い方 しかし実際は、こう詰められるはず コア1 コア2 コア3 wait終了 wait終了 コア1 コア2 コア3 6 5 4 3 2 1 16 25 34
  10. 10. xargsを使う方法
  11. 11. xargsを使う方法 つい最近知った。参考記事: • xargs を使ってカジュアルに並列処理 - たごもりすメモ http://tagomoris.hatenablog.com/entry/20110513/1305267021 • xargsは通常、「標準入力から受け取った内容を繋げた コマンドを作り実行する」のに使うものなのだが • その際に、コマンドを1つだけ作るのではなく複数作ると いうオプション(「-L」や「-n」)があり、 • しかも、それを並列実行するオプション(「-P」)もある ※POSIX標準ではない。GNUにはある。
  12. 12. xargsを使う方法 • 普通、xargsは「標準入力から受け取った値を コマンドの引数にまとめて渡す」。 seq 1 3 | xargs echo # "echo 1 2 3" と同等 • -Lオプションを付けると、標準入力から受け取った値を 何行ずつ区切って渡すかを指定できる。 それらは個別に順次実行される。 seq 1 3 | xargs -L 1 echo # ↑"echo 1; echo 2; echo 3" と同等 seq 1 3 | xargs -L 1 sleep # 6秒待つ(1+2+3で) • -Pオプションを付けると、その個数上限で並列実行する。 seq 1 3 | xargs -L 1 -P 3 sleep # 待つのは3秒だけ # (1秒待つ・2秒待つ・3秒待つのを並列実行している)
  13. 13. GNU parallelを使う方法
  14. 14. GNU parallelを使う方法 • さっきの記事で挙げられていて知った • 参考記事 – コマンドを並列に実行するGNU parallelがとても便利 - りんごがでている http://bicycle1885.hatenablog.com/entry/2014/08/10/143612 – GNU Parallel作者が書いたParallel: The Command-Line Power Toolを読んだ | Siguniang's Blog https://siguniang.wordpress.com/2012/09/09/ notes-on-gnu-parallel-the-command-line-power-tool/
  15. 15. GNU parallelを使う方法 使い方 # -j 1 だとただの逐次実行 seq 4 3 10 | parallel -j 1 'echo sleep {} start; sleep {}; echo sleep {} end: `date`' 【結果】 sleep 4 start sleep 4 end: 2017年 10月 7日 土曜日 13:54:59 JST sleep 7 start sleep 7 end: 2017年 10月 7日 土曜日 13:55:07 JST sleep 10 start sleep 10 end: 2017年 10月 7日 土曜日 13:55:17 JST
  16. 16. GNU parallelを使う方法 使い方 # -j 3 で3つすべてを並列に実行 seq 4 3 10 | parallel -j 3 'echo sleep {} start; sleep {}; echo sleep {} end: `date`' 【結果】 sleep 4 start sleep 4 end: 2017年 10月 7日 土曜日 13:54:23 JST sleep 7 start sleep 7 end: 2017年 10月 7日 土曜日 13:54:26 JST sleep 10 start sleep 10 end: 2017年 10月 7日 土曜日 13:54:29 JST
  17. 17. GNU parallelを使う方法 使い方 # -j 2 だと、「4秒待つ」と「7秒待つ」のどちらか(=前者)が # 終わってから、「10秒待つ」が実行される seq 4 3 10 | parallel -j 2 'echo sleep {} start; sleep {}; echo sleep {} end: `date`' 【結果】 sleep 4 start sleep 4 end: 2017年 10月 7日 土曜日 13:54:39 JST sleep 7 start sleep 7 end: 2017年 10月 7日 土曜日 13:54:42 JST sleep 10 start sleep 10 end: 2017年 10月 7日 土曜日 13:54:49 JST
  18. 18. GNU parallelを使う方法 使い方 # 括弧やリダイレクトがそのまま書けるのもポイント高いところ seq 4 3 10 | parallel -j 1 '(echo sleep {} start; sleep {}; echo sleep {} end: `date`) > log{}.txt' これを実行すると、先程の内容が、それぞれ log4.txtとlog7.txtとlog10.txtに保存される
  19. 19. おまけ: 全プログラムをなるべく早く 終わらせるためのポイント
  20. 20. おまけ • 終了までの時間を早くしたければ、基本的には「実行時間が 長いものから実行する」のがよい。 ただ、完全に最適な実行時間にしたければ、全組み合わせを 試すのに相当する程度の時間はかかる。 • 同時並列数を固定とした場合、 – (すべての並び順を考慮して)終了までの時間を 最適化した場合の時間と、 – 単に「実行時間が長いものから実行する」とした場合での 終了までの時間を比べると、 後者は前者の(1 + 1/3)倍以内で収まることが知られている。 Graham, R. L. (1969). "Bounds on multiprocessing timing anomalies". SIAM journal on Applied Mathematics, 17(2), 416-429.

×