基本4の補足(eachでの速度検証)
eachを利用すれば、各々のファイル毎で並列処理を行うことができます。このとき、各タスクごとに入力ファイルがコピーされ、処理が進んでいきます。
しかし、異なるタスクで同じ入力ファイルを使うときでも毎回コピー処理が行われると、無駄なコピー処理が発生する、という問題があります。
そこでPIONEでは、同じファイルについてはリンクを作成・使用することによって、逐次コピーする時間を削減しています。
例えば、下記のようなmrcファイルの情報を出力する2つのコードがあったとします。
(1)は全てのファイル(A.mrc, B.mrc, C.mrc, D.mrc, E.mrc)について1回ずつSizeOutを呼び、
(2)は1つのA.mrcファイルについて5回SizeOutを呼ぶ仕組みとしています。
サイズの大きいファイル(512×512×512のmrc画像: mrcImageNullImageCreateを使用)を入力として動作を比較します。
コード | 入力ファイル | 1ファイル毎のSizeOut | 処理結果(ProM) | |
---|---|---|---|---|
(1) |
Rule Main input '*.mrc' output '*.txt'.all Flow rule SizeOut {val:1} End Rule SizeOut input '*.mrc' output '{$I[1][1]}{$val}.txt' param $val Action wc {$I[1]} > {$O[1]} End |
A.mrc |
1回 | ![]() |
(2) |
Rule Main input 'A.mrc' output '*.txt'.all Flow rule SizeOut {val:1.upto(5)} End Rule SizeOut input 'A.mrc' output 'A{$val}.txt' param $val Action wc {$I[1]} > {$O[1]} End |
A.mrc |
5回 | ![]() |
いずれにしてもSizeOutは5回処理されていますが、(2)の場合は(1)に比べ時間が削減されています。
同じマシン内においてeachの処理ではリンクを利用することにより同じ入力ファイルを何度もコピーすることを避けていることが確認できます。
つまり入力ファイルのサイズを特に気にすることなくeachで並列処理を行えることが分かります。
では、eachとallの速度の違いを見てみましょう。
いずれもA.mrcの情報をそれぞれ5回出力している処理ですが、(3)ではSizeOutをall出力とし、(4)ではSizeOutをeach出力としています。
eachを実行するときはpione-clientのオプション-t 5として5つの並列処理を行って、動作を比較してみます。
コード | 処理結果(ProM) | |
---|---|---|
(3) all |
Rule Main input 'A.mrc' output '*.txt'.all Flow rule SizeOut End Rule SizeOut input 'A.mrc' output '*.txt'.all Action for (( i=1; i<6; i++ )) do wc {$I[1]} > "{$I[1][1]}$i.txt" done End |
![]() |
(4) each |
Rule Main input 'A.mrc' output '*.txt'.all Flow rule SizeOut {val:1.upto(5)} End Rule SizeOut input 'A.mrc' output '{$I[1][1]}{$val}.txt' param $val Action wc {$I[1]} > {$O[1]} End |
![]() |