RubyGCHack

ここ一週間でRubyGCを弄って遊んだ。
何とか早くしようとがんばったけど、
Mark&Sweepのシンプルさの前に完敗。。。
 
■Hack内容
 ・世代別GCを取り入れる
 ・ライトバリアはOld世代からの参照をたどる事で実現する。
   *Matz日記より Matzにっき(2007-06-30)
■ソース 
  TreadmillGCを使ってインクリメンタルGC(Minorのみ)を作った。
  gc_new_inc.c
 
ベンチマーク
 algorithmで紹介されている
 Life.rbを使ってベンチマークを取った。(このサイトはすっごく便利)

//現在のGC
all GC time = 1161
all GC cnt = 435
min GC time = 2
max GC time = 6
minor GC cnt = 0
major GC cnt = 435
add_heap cnt = 2
ave GC time = 2.66896551724138
ave mark time = 0.448275862068966
ave sweep time = 2.08275862068966
 
//新しく作ったGC
all GC time = 1374
all GC cnt = 441
min GC time = 0
max GC time = 9
minor GC cnt = 439
major GC cnt = 2
add_heap cnt = 3
ave GC time = 3.1156462585034
ave minor mark time = 0.539863325740319
ave minor sweep time = 2.40091116173121
ave major mark time = 0.5
ave major sweep time = 5.0

 (各フェイズのコストを見るためGCカウントを故意に合わせた)
ぶはっ!おっせ!
Treadmillはやめて普通のSweepしよー。
 
■ソース
  現在GCのSweep処理と同じアルゴリズム
  gc_non_inc.c
 
ベンチマーク

//現在のGC
all GC time = 1161
all GC cnt = 435
min GC time = 2
max GC time = 6
minor GC cnt = 0
major GC cnt = 435
add_heap cnt = 2
ave GC time = 2.66896551724138
ave mark time = 0.448275862068966
ave sweep time = 2.08275862068966
 
//新しく作ったGC
all GC time = 1261
all GC cnt = 477
min GC time = 2
max GC time = 7
minor GC cnt = 476
major GC cnt = 1
add_heap cnt = 2
ave GC time = 2.64360587002096
ave minor mark time = 0.502100840336134
ave minor sweep time = 1.92857142857143
ave major mark time = 1.0
ave major sweep time = 2.0

まぁまぁ。でも、早くない。がっかり。orz...
 
■結論
 ・この方式のライトバリアはMark時に結構なコストがかかる。(その分GC以外のRuby処理時間には影響しない)
 ・そのわり思ってたほどSweepが劇的には早くなっていない。
 
 
。。。まだ、あきらめる気はない。