プログラムを並列処理する 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 というプログラム(sem は parallel –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
- マニュアル(文章の構成が今ひとつで、読みづらい)
http://www.gnu.org/software/parallel/man.html - 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
To avoid mistyping try using TAB to complete the name. On my system I can write ‘para’ which results in parallel being spelled out as it is the only command starting with para.
If you have not watched the intro videos, do that now: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
Hej, oletange. Yea, I can’t live without tab completion. I’ll check out youtube videos later.
When you have the time walk through the new tutorial: http://www.gnu.org/software/parallel/parallel_tutorial.html Your command line will love you for it.