MCP (MultiCore Parser)を使ってみる、その2 (集計)

前回の記事 (MCP (MultiCore Parser)を使ってみる) で集計も試してみたいと書きました。その後集計のためのコードを書いていたのですが上手く行かず諦めてgithubのissueで聞いてみたところexampleをいただいたので試してみます (MCP作者のKanatokoさんには感謝!です)。

結論から書くと、MCPはawkやperlの倍程度、高速に処理出来ました!

# githubからcloneします
$ git clone https://github.com/Kanatoko/MCP
$ cd MCP

# ビルドします
$ ant

# 動かしてみます(参考→ https://github.com/Kanatoko/MCP/issues/1 )
$ seq 100 | java -cp output/mcp.jar net.jumperz.app.MCP.MCP net.jumperz.io.multicore.example.MSum
5050

というわけで出来ました!さてせっかくマルチコアで動くのでいろいろとやってみます。

まず、データサイズ大きめな、連番が含まれるファイルを作ります。

# 2つほど作ります
$ seq -f %.0f 10000000 > 10M.data

# データサイズは以下のようになっています
$ ls -sh1 *.data
 76M 10M.data

########
# 比較 #
########

# まずはawkとperlで速度を計測してみます
# awkやperl、または内部のコードより優れた方法があったら教えてください。
# 3回実行して、最後の一回の値を採用します、ファイルのキャッシュ対策です(*キャッシュする*という意味です)

# 10M.data
$ time cat 10M.data | awk '{s+=$1}END{printf "%.0f\n", s}'
50000005000000

real	0m3.500s
user	0m3.412s
sys	0m0.756s
$ time cat 10M.data | perl -e '$sum = 0; while (<>) { $sum += $_; } print $sum'
50000005000000
real	0m2.438s
user	0m2.384s
sys	0m0.516s

さてここまでで、既存の手法で行いました。次はMCPを使ってみます。マシンは、

– CPU: Opteron3280 (8コア)
– Ubuntu 12.04.5 LTS
– Linux Kernel: 3.8.0-44-generic
– java version “1.7.0_75” OpenJDK Runtime Environment (IcedTea 2.5.4) (7u75-2.5.4-1~precise1) OpenJDK 64-Bit Server VM (build 24.75-b04, mixed mode)
です。

# まずは10M.dataをデフォルトの設定で行います
# realとuserの比を見ると、3~4コア程度使っているようですね
$ time cat 10M.data | java -cp output/mcp.jar net.jumperz.app.MCP.MCP net.jumperz.io.multicore.example.MSum
50000005000000

real	0m5.343s
user	0m17.848s
sys	0m0.924s

# 並列度を、1コアから8コアまでやってみます
$ time cat 10M.data | java -cp output/mcp.jar net.jumperz.app.MCP.MCP --thread-count 1 net.jumperz.io.multicore.example.MSum
50000005000000

real	0m2.486s
user	0m2.616s
sys	0m0.588s

$ time cat 10M.data | java -cp output/mcp.jar net.jumperz.app.MCP.MCP --thread-count 2 net.jumperz.io.multicore.example.MSum
50000005000000

real	0m1.777s
user	0m2.984s
sys	0m0.660s

$ time cat 10M.data | java -cp output/mcp.jar net.jumperz.app.MCP.MCP --thread-count 3 net.jumperz.io.multicore.example.MSum
50000005000000

real	0m3.170s
user	0m7.412s
sys	0m0.652s

$ time cat 10M.data | java -cp output/mcp.jar net.jumperz.app.MCP.MCP --thread-count 4 net.jumperz.io.multicore.example.MSum
50000005000000

real	0m5.471s
user	0m17.828s
sys	0m0.908s

$ time cat 10M.data | java -cp output/mcp.jar net.jumperz.app.MCP.MCP --thread-count 5 net.jumperz.io.multicore.example.MSum
50000005000000

real	0m5.366s
user	0m19.192s
sys	0m1.152s

$ time cat 10M.data | java -cp output/mcp.jar net.jumperz.app.MCP.MCP --thread-count 6 net.jumperz.io.multicore.example.MSum
50000005000000

real	0m6.041s
user	0m23.832s
sys	0m1.436s

$ time cat 10M.data | java -cp output/mcp.jar net.jumperz.app.MCP.MCP --thread-count 7 net.jumperz.io.multicore.example.MSum
50000005000000

real	0m7.049s
user	0m29.436s
sys	0m1.660s

$ time cat 10M.data | java -cp output/mcp.jar net.jumperz.app.MCP.MCP --thread-count 8 net.jumperz.io.multicore.example.MSum
50000005000000

real	0m9.359s
user	0m42.464s
sys	0m2.496s

↑の結果としては2コアが最速でawkやperlを上回りました。

まとめると次のようになります。

表: 1,2,3…の連番が格納されている10MBのファイルの処理性能
ソフトウェア 処理時間 (sec)
awk 3.50
Perl 2.43
MCP (1 core) 2.48
MCP (2 cores) 1.77
MCP (3 cores) 3.17
MCP (4 cores) 5.47
MCP (5 cores) 5.36
MCP (6 cores) 6.04
MCP (7 cores) 7.04
MCP (8 cores) 9.35

ついでに100MB($ seq -f %.0f 100000000 > 100M.data)のときも試してみました。

表: 1,2,3…の連番が格納されている100MBのファイルの処理性能
ソフトウェア 処理時間 (sec)
awk 34.45
Perl 24.76
MCP (1 core) 22.11
MCP (2 cores) 17.38
MCP (4 cores) 52.10
MCP (8 cores) 105.60

↑では、MCP@2coresのとき最速です!

総評として、

– MCP@2coresはperlやawkより早い
– MCPは並列度2を超えると速度低下する傾向あり

といったところでしょうか。

Bookmark the permalink.

Comments are closed.