GNU Parallel作者が書いたParallel:The Command-Line Power Toolを読んだ

プログラムを並列処理する GNU Parallel というプログラムがある。このプログラムの作者 Ole Tange usenix February 2011, Volume 36, Number 1 “The Command-Line Power Tool” という記事を書いていたので読んでみた。6ページで GNU Parallel の主要機能がひと通り解説されているので、GNU Parallel の機能をピンポイントでしか知らない人(=自分)が読むと、いろいろと使いどころが湧いて来ると思う。

GNU Parallel: The Command-Line Power Tool
February 2011, Volume 36, Number 1
Authors: Ole Tange
https://www.usenix.org/publications/login/february-2011-volume-36-number-1/gnu-parallel-command-line-power-tool

History of GNU Parallel

まずは GNU Parallel の生い立ち。
xargs を改善した xxargs と並列処理をする parallel という2つのプログラムが合体して現在の parallel に発展した

GNU Parallel therefore has two main objectives: replace xargs and run commands in parallel.

Your First Parallel Job

Reading Input

入力はコマンドラインでもパイプでも渡せる

$ find . -type f | parallel gzip

セパレータを正規表現で書くと(–colsep)、TSV/CSVファイルをカラム単位で処理することもできる。

$ cat filelist.tsv | parallel --colsep '\t' diff {1} {2} ">" {3}

Building the Command to Run

xargs 的な処理

$ ls *.gz | parallel mv {} archive

コマンドなしの parallel にパイプで文字列を渡すと、各文字列はコマンドとして処理される

$ (echo ls; echo grep root /etc/passwd) | parallel

Controlling the Output

並列実行される各ジョブの実行結果は、ジョブが終了した時点で出力される。
-u オプションをつけると、バッファリングされずに各ジョブの実行結果が混在して出力される。

$ parallel traceroute ::: foss.org.my debian.org freenetproject.org

-k オプションをつけると、各ジョブは並列で実行されるが、出力はコマンドの順に行われる。

$ paparallel -k echo {}';' sleep {} ::: 3 2 1 4
3
2
1
4

Execution of the Jobs

デフォルトでは 1コアあたり1ジョブ。

  • -j4 とすればコアに関係なく4並列で実行され、
  • -j200% とすれば1コアあたり200%稼働でジョブが実行される。

2コアの場合、-j4 と -j200% ではともに4ジョブ並列で実行されることになる。
デフォルト(2コア)での挙動

$ parallel sleep {} ::: 10 20 30 40 &
[1] 622
$ pstree -p 622
parallel(622)-+-sleep(654)
              `-sleep(655)

4並列で走らせる

$ parallel -j4 sleep {} ::: 10 20 30 40 &
[2] 664
$ pstree -p 664
parallel(664)-+-sleep(697)
              |-sleep(698)
              |-sleep(699)
              `-sleep(700)

なお、コア数は以下のコマンドで確認できる。

$ grep processor /proc/cpuinfo | wc -l

parallel で実行中のジョブを表示するには、USR1 シグナルを送信する

$ killall -USR1 parallel
parallel: sleep 30
parallel: sleep 20
parallel: sleep 40
parallel: sleep 10

Remote Computers

各ジョブをリモートで実行させることも可能。

$ parallel --sshlogin xxx@host1,xxx@host2 hostname';' sleep {} ::: 10 20 30 40

各サーバでジョブが完了すると、新しいジョブをふるようになっている模様。

Transferring Files

ローカルのファイルをリモートサーバに転送(–transfer)してコマンドを実行し、実行結果のファイルを受け取る(–return)ことも可能。
–cleanup をつけることで、リモートサーバに転送したファイルはジョブ終了後に削除される。

$ parallel -S xxx@host1,xxx@host2 --transfer --return {.}.bz2 --cleanup zcat '< {} | bzip2 >{.}.bz2' ::: *.gz

GNU Parallel as Part of a Script

GNU Parallel には sem というプログラム(semparallel –semaphore のエイリアス)があり、計量型セマフォミューテックスとして利用できる。

for i in `ls *.log` ; do
 [... a lot of complex lines here ...]
 sem -j4 --id my_id do_work $i
done
sem --wait --id my_id

–id はセマフォ名。 -j1 とすればミューテックス(binary semaphore)。

GNU Parallel as a Job Queue Manager

FIFO のようにコマンドを順次実行できる

$ echo >jobqueue; tail -f jobqueue | parallel
$ echo my_command my_arg >> jobqueue

inotify でファイルシステムを監視し、変更のあったファイルを parallel で処理することもできる

$ inotifywait -q -m -r -e CLOSE_WRITE --format %w%f my_dir | parallel -u echo

※inotifywait は inotify-tools の1コマンド。

 雑感

  • 名前から並列実行のためのプログラムとおもいきや、xargs 的な処理も充実している。
  • 過信して使うと rsync のように “shoot yourself in the foot” なあやしい雰囲気満載
  • 日本人としては、脳内で「パラレル、パラレル」と唱えつつも、l と r がグチャグチャになって “pararel” など誤った綴りでコマンドを入力してしまい、“command not found” になりやすいのが玉に瑕。
  • GNU Parallel ロゴの錯視は Café Wall Illusion

References

  1. マニュアル(文章の構成が今ひとつで、読みづらい)
    http://www.gnu.org/software/parallel/man.html
  2. Ole Tange : “GNU Parallel: The Command-Line Power Tool”, issue: February 2011, Volume 36, Number 1
    https://www.usenix.org/publications/login/february-2011-volume-36-number-1/gnu-parallel-command-line-power-tool

4 thoughts on “GNU Parallel作者が書いたParallel:The Command-Line Power Toolを読んだ

Leave a comment