nariです。

2011年7月2日19:29 KOSAKI Motohiro <kosaki.motohiro / gmail.com>:
>> 本当はgc_mark()の際に毎回stack_check()するのがいいと思うのですが、
>> そうするとGCの性能が落ちてしまうので、大体で決めてしまうしかないのか
>> なと思ってます。
>
> ところで、これって測定済みですか?
> stack_check()ってespを変数にmovして、引き算一発なので、なにがそんなに
> 遅いんだろうかと。
> espに対するmovってきっと普通のmovとは違う処理が走ってるので mov eaxとかと
> 同じ速度が出せる気はまったくしませんが、所詮 gcって slow pathなので
> そんなに効くかなぁ と
>
>

以下のパッチで測ってみました。

diff --git a/gc.c b/gc.c
index d5b8dfd..1709897 100644
--- a/gc.c
+++ b/gc.c
@@ -1614,7 +1614,7 @@ gc_mark(rb_objspace_t *objspace, VALUE ptr, int lev)
     obj->as.basic.flags |= FL_MARK;
     objspace->heap.live_num++;

-    if (lev > GC_LEVEL_MAX || (lev == 0 && stack_check())) {
+    if (lev > GC_LEVEL_MAX || stack_check()) {
        if (!mark_stack_overflow) {
            if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) {
                *mark_stack_ptr = ptr;

以下のプログラムでGC時間を測ってみました。

GC::Profiler.enable
a = []
10000000.times{a << "a".dup}
p GC::Profiler.total_time

パッチ適用後: 1.410000000000001
バッチ適用前: 1.4899999999999998

と、4%くらい劣化してます。
これくらいなら入れしまっていいかもしれませんが。
うーん、バグ修正で4%も性能が落ちるのはなぁと正直悩んでます…。

-- 
Narihiro Nakamura (nari)