Casual verification for multi-thread programs in C++/Java/Go/Scala on AWS EC2

ローカルだとどうしても限界があるので、EC2のマルチコアのインスタンスを使って、マルチスレッドのプログラムがうまく動いているかどうかを確認。 プログラムがちゃんと終了して、各インスタンスで結果(順序は不問)が同じで、コア数に応じて速くなっていれば良し。

EC2のスポットインスタンスを使って最も安いリージョンでおよそ、c3.xlarge(4コア)だと$0.5/12hrs、c3.2xlarge(8コア)で$0.8/12hrs。

値段が安いほどTerminateされる確率は高くなるので注意。

nishidy/ParseWikipediaXML · GitHub

実装はC++/Java/Go/Scala

プログラム実行は共通して、

  • Wikipedia英語版XMLデータベースの先頭から10万行を使用(microインスタンスのリソース量に合わせて小さめ)
  • メインスレッドで各ページごとにキュー/チャネルなどに渡し、ワーカースレッド/アクターがそれを受けてパースするかたち
  • 各ページにおけるbag-of-words(単語とその頻度)をファイルに出力
  • 単語は、アルファベット/数字/ダッシュ、のみを含むものが対象
  • 英語の辞書ファイルを用いて、活用形を原形に戻した状態で単語を取り扱う(stopwordは除く)
  • 頻度数2以上の単語、1000〜10000語を含むページ、が出力対象

なお、Scalaはsbt runで出力される時間を記録。

それぞれの実装の中身はおおよそ同じように作ってあるけれど、使用するCPUとかをきちんと合わせておらず、各実装は独立していると考えているので、比較対象は同一実装の別インスタンスになる。(実際、取得できる結果は違う)

それぞれのプログラムを何回か走らせてから結果を取得しているので、ディスクキャッシュは効いているはず。

C++

t2.micro

real 0m6.446s
user 0m6.384s
sys  0m0.044s

c3.xlarge

real 0m3.140s
user 0m8.300s
sys  0m0.052s

c3.2xlarge

real 0m2.139s
user 0m7.340s
sys  0m0.068s

Java

t2.micro

real 0m8.775s
user 0m8.604s
sys  0m0.144s

c3.xlarge

real 0m3.935s
user 0m8.976s
sys  0m0.188s

c3.2xlarge

real 0m2.403s
user 0m14.376s
sys  0m0.304s

Go

t2.micro

real 0m10.780s
user 0m10.424s
sys  0m0.308s

c3.xlarge

real 0m5.033s
user 0m13.192s
sys  0m0.452s

c3.2xlarge

real 0m2.795s
user 0m16.300s
sys  0m0.620s

Scala

t2.micro

[success] Total time: 22 s, completed ...

c3.xlarge

[success] Total time: 14 s, completed ...

c3.2xlarge

[success] Total time: 13 s, completed ...