From: nobu.nakada@... Date: 2002-12-31T06:37:47+09:00 Subject: [ruby-dev:19252] Re: [1.8] speed なかだです。 At Tue, 31 Dec 2002 01:42:16 +0900, Tanaka Akira wrote: > > 一度大量にオブジェクトを作って解放すると live に対して freed が > > 大きくなり、malloc_limit が増えにくくなることが考えられます。 > > 私も今の freed はあんまりアプリケーションのメモリ使用量を推定するには > 向いていない値な気がします。 手抜きです。実は最初、garbageという変数で解放するオブジェクトを 数えるようにしてみたんですが、ほとんど制限にならなかったんで freedを使ってお茶を濁しました。 > もちろん、malloc/realloc 量とオブジェクト数の増加量に相関があることが > 前提ですけど。 あることはあると思いますが、あまり正確ではないでしょう。あくま でも目安程度ってことで。 At Tue, 31 Dec 2002 02:33:06 +0900, Tanaka Akira wrote: > ふと思ったのですが、もしかしたら、メモリの量だけで制御するのではなく、 > GC の時間と間隔も考慮すべきなのかも知れません。GC にかかる時間は測れま > すから、GC 間隔を制御すれば割合を一定以下に抑えることは可能です。そし > て、そういう制御をすれば GC による速度低下を(メモリの量による制御より > も)もっと直接的に制御できます。例えば、GC にかかった時間と同じだけの時 > 間は GC を起動しないようにすれば、GC の割合は 50% に抑えられるのは自明 > です。 試してみました。[ruby-talk:59662]などはかなり向上しますが、 [ruby-dev:18482]や[ruby-dev:19242]あたりはほとんど変わらないよ うです。比率を調整するとちょっと違うかも知れませんが。 Index: configure.in =================================================================== RCS file: /cvs/ruby/src/ruby/configure.in,v retrieving revision 1.158 diff -u -2 -p -r1.158 configure.in --- configure.in 26 Dec 2002 15:12:06 -0000 1.158 +++ configure.in 30 Dec 2002 21:23:18 -0000 @@ -378,5 +377,5 @@ AC_CHECK_FUNCS(fmod killpg wait4 waitpid setitimer setruid seteuid setreuid setresuid setproctitle\ setrgid setegid setregid setresgid pause lchown lchmod\ - getpgrp setpgrp getpgid setpgid getgroups getpriority getrlimit\ + getpgrp setpgrp getpgid setpgid getgroups getpriority getrlimit getrusage\ dlopen sigprocmask sigaction _setjmp setsid telldir seekdir fchmod\ mktime timegm cosh sinh tanh) Index: gc.c =================================================================== RCS file: /cvs/ruby/src/ruby/gc.c,v retrieving revision 1.114 diff -u -2 -p -r1.114 gc.c --- gc.c 29 Dec 2002 14:51:22 -0000 1.114 +++ gc.c 30 Dec 2002 21:27:14 -0000 @@ -874,4 +874,30 @@ size_of_table(tbl) } +#ifdef HAVE_GETRUSAGE +static struct timeval * +period(t) + struct timeval *t; +{ + struct rusage u; + getrusage(RUSAGE_SELF, &u); + *t = u.ru_utime; + return t; +} + +static double +laptime(t1, t2) + const struct timeval *t1, *t2; +{ + return (t1->tv_sec - t2->tv_sec) + (t1->tv_usec - t2->tv_usec) / 1000000.0; +} +static struct timeval gc_start_time, gc_end_time; +#define PERIOD(t) period(&(t)) +#define LAP(t1, t2) laptime(&(t1), &(t2)) +#else +static time_t gc_start_time, gc_end_time; +#define PERIOD(t) time(&(t)) +#define LAP(t1, t2) difftime(t1, t2) +#endif + static void gc_sweep() @@ -881,4 +907,5 @@ gc_sweep() int i, j; unsigned long live = 0, garbage = 0; + double gc, work; if (ruby_in_compile && ruby_parser_stack_on_heap()) { @@ -911,4 +938,5 @@ gc_sweep() if (p->as.basic.flags) { obj_free((VALUE)p); + garbage++; } if (need_call_final && FL_TEST(p, FL_FINALIZE)) { @@ -916,4 +944,5 @@ gc_sweep() p->as.free.next = final_list; final_list = p; + garbage++; } else { @@ -947,6 +976,12 @@ gc_sweep() } } - malloc_limit += malloc_increase; - malloc_limit *= (double)live / (live + freed); + + work = LAP(gc_start_time, gc_end_time); + PERIOD(gc_end_time); + gc = LAP(gc_end_time, gc_start_time); + if (work < gc * 2) + malloc_limit += GC_MALLOC_LIMIT; + else if (live < garbage * 2) + malloc_limit /= 2; if (malloc_limit < GC_MALLOC_LIMIT) malloc_limit = GC_MALLOC_LIMIT; malloc_increase = 0; @@ -1132,4 +1167,5 @@ rb_gc_mark_frame(frame) mark_locations_array(frame->argv, frame->argc); rb_gc_mark(frame->cbase); + rb_gc_mark((VALUE)frame->node); } @@ -1189,4 +1225,6 @@ rb_gc() if (during_gc) return; during_gc++; + + PERIOD(gc_start_time); init_mark_stack(); -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦