実行プロファイルの取得とparallel-mark
追記 : コメント参照, http://d.hatena.ne.jp/mjt/20090702/p2
moshとypsilonを比較すると、マイクロベンチマークではmoshが速いが、現実的なアプリケーションではypsilonの方が2〜10倍高速だということが多い。
研究ではmoshを単に接続管理用にしか使っていない*1ので大きな問題にはならないが、(昨日のような)"ちょっとした日常のプログラミング"でもypsilonではなくmoshも使いたいのでボトルネックを検討する必要が有る。
moshには備え付けのプロファイラが有るが、使い方が不明なのとサンプルファイルを何故かtmpに作るので使わず、まずは普通にgprofする。
gprofを使うためにはオプション-pgをCXXFLAGSやCFLAGSに足す。もちろんプロファイラはフレームポインタが必要なので-fomit-frame-pointerはconfigure後にMakefileを修正して取り除く必要が有る。
昨日のプログラムのループ回数を50回から2回に減らして実行すると :
% cumulative self self total time seconds seconds calls s/call s/call name 63.67 116.47 116.47 11080886 0.00 0.00 GC_mark_from 10.31 135.32 18.85 847782669 0.00 0.00 GC_header_cache_miss 4.68 143.89 8.57 15019965 0.00 0.00 scheme::VM::run
簡単に言えば、70%の時間はGCに費やされている。ypsilonはmostly concurrent GCなのでこの70%の時間を別のCPUで実行できる。
- 特にオプション無し :
real 2m20.074s user 2m19.093s sys 0m0.445s
単純にsvnをチェックアウトして./configure、実行した場合。
- enable-parallel-mark
real 2m4.363s user 2m57.478s sys 0m0.741s
15秒ほど高速化した。余計なロックが必要になるため、single coreシステムでは必要以上に遅くなるかもしれない。
もっとも、Boehm GCはN coreのシステムではmark threadを(N-1)つしか起動しない。この高速化はfree-listの作成などが並列化されることによると考えている。
gcをリポジトリのではなく公式のものに入れ替えて適切に設定しても数秒しか高速化しない。
- (参考) ypsilon
real 0m12.913s user 0m22.013s sys 0m3.288s
ypsilonの場合はほぼ常に2つのCPUが動作する。ypsilonはデザイン上の都合から、GCを常に動作させる必要が有る。