[前][次][番号順一覧][スレッド一覧]

ruby-changes:36332

From: ko1 <ko1@a...>
Date: Fri, 14 Nov 2014 05:17:16 +0900 (JST)
Subject: [ruby-changes:36332] ko1:r48413 (trunk): * gc.c: Tuning RincGC parameters.

ko1	2014-11-14 05:16:59 +0900 (Fri, 14 Nov 2014)

  New Revision: 48413

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=48413

  Log:
    * gc.c: Tuning RincGC parameters.
      Before this patch, gc_marks_step() marks (white -> grey) fixed
      number objects. However, this strategy does not fit practical
      cases, for example too slow to make progres.
      This patch changes this strategy how many objects the
      gc_marks_step() should handle.
      We can estimate how many times gc_marks_step() is called during
      this major marking (== C) with the free slot number in pooled
      pages. We also can estimate the living object number (== L)
      using last marked_slots value. We can solve this problem (how
      many objects should be process in gc_marks_step()) by L/C.
    * gc.c (rb_objspace_t): add rb_objspace_t::rincgc::pooled_sltos and
      step_slots.

  Modified files:
    trunk/ChangeLog
    trunk/gc.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 48412)
+++ ChangeLog	(revision 48413)
@@ -1,3 +1,23 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri Nov 14 04:51:18 2014  Koichi Sasada  <ko1@a...>
+
+	* gc.c: Tuning RincGC parameters.
+
+	  Before this patch, gc_marks_step() marks (white -> grey) fixed
+	  number objects. However, this strategy does not fit practical
+	  cases, for example too slow to make progres.
+
+	  This patch changes this strategy how many objects the
+	  gc_marks_step() should handle.
+
+	  We can estimate how many times gc_marks_step() is called during
+	  this major marking (== C) with the free slot number in pooled
+	  pages. We also can estimate the living object number (== L)
+	  using last marked_slots value. We can solve this problem (how
+	  many objects should be process in gc_marks_step()) by L/C.
+
+	* gc.c (rb_objspace_t): add rb_objspace_t::rincgc::pooled_sltos and
+	  step_slots.
+
 Fri Nov 14 01:26:47 2014  Shugo Maeda  <shugo@r...>
 
 	* lib/net/imap.rb (search_response): parse MODSEQ in SEARCH
Index: gc.c
===================================================================
--- gc.c	(revision 48412)
+++ gc.c	(revision 48413)
@@ -586,6 +586,12 @@ typedef struct rb_objspace { https://github.com/ruby/ruby/blob/trunk/gc.c#L586
 	size_t error_count;
 #endif
     } rgengc;
+#if USE_RINCGC
+    struct {
+	size_t pooled_slots;
+	size_t step_slots;
+    } rincgc;
+#endif
 #endif /* USE_RGENGC */
 } rb_objspace_t;
 
@@ -1281,12 +1287,17 @@ heap_add_freepage(rb_objspace_t *objspac https://github.com/ruby/ruby/blob/trunk/gc.c#L1287
     }
 }
 
-static inline void
+static inline int
 heap_add_poolpage(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *page)
 {
     if (page->freelist) {
 	page->free_next = heap->pooled_pages;
 	heap->pooled_pages = page;
+	objspace->rincgc.pooled_slots += page->free_slots;
+	return TRUE;
+    }
+    else {
+	return FALSE;
     }
 }
 
@@ -3187,8 +3198,10 @@ gc_sweep_start_heap(rb_objspace_t *objsp https://github.com/ruby/ruby/blob/trunk/gc.c#L3198
 {
     heap->sweep_pages = heap->pages;
     heap->free_pages = NULL;
+#if GC_ENABLE_INCREMENTAL_MARK
     heap->pooled_pages = NULL;
-
+    objspace->rincgc.pooled_slots = 0;
+#endif
     if (heap->using_page) {
 	RVALUE **p = &heap->using_page->freelist;
 	while (*p) {
@@ -3288,8 +3301,9 @@ gc_sweep_step(rb_objspace_t *objspace, r https://github.com/ruby/ruby/blob/trunk/gc.c#L3301
 	}
 	else if (sweep_page->free_slots > 0) {
 	    if (need_pool) {
-		need_pool = FALSE;
-		heap_add_poolpage(objspace, heap, sweep_page);
+		if (heap_add_poolpage(objspace, heap, sweep_page)) {
+		    need_pool = FALSE;
+		}
 	    }
 	    else {
 		heap_add_freepage(objspace, heap, sweep_page);
@@ -4205,6 +4219,7 @@ gc_mark_stacked_objects(rb_objspace_t *o https://github.com/ruby/ruby/blob/trunk/gc.c#L4219
     VALUE obj;
 #if GC_ENABLE_INCREMENTAL_MARK
     size_t marked_slots_at_the_beggining = objspace->marked_slots;
+    size_t popped_count = 0;
 #endif
 
     while (pop_mark_stack(mstack, &obj)) {
@@ -4221,8 +4236,9 @@ gc_mark_stacked_objects(rb_objspace_t *o https://github.com/ruby/ruby/blob/trunk/gc.c#L4236
 		rb_bug("gc_mark_stacked_objects: incremental, but marking bit is 0");
 	    }
 	    CLEAR_IN_BITMAP(GET_HEAP_MARKING_BITS(obj), obj);
+	    popped_count++;
 
-	    if (objspace->marked_slots - marked_slots_at_the_beggining > count) {
+	    if (popped_count + (objspace->marked_slots - marked_slots_at_the_beggining) > count) {
 		break;
 	    }
 	}
@@ -4857,17 +4873,22 @@ gc_marks_start(rb_objspace_t *objspace, https://github.com/ruby/ruby/blob/trunk/gc.c#L4873
     gc_report(1, objspace, "gc_marks_start: (%s)\n", full_mark ? "full" : "minor");
     gc_stat_transition(objspace, gc_stat_marking);
 
-    objspace->marked_slots = 0;
-
 #if USE_RGENGC
     objspace->rgengc.old_objects_at_gc_start = objspace->rgengc.old_objects;
 
     if (full_mark) {
+#if GC_ENABLE_INCREMENTAL_MARK
+	objspace->rincgc.step_slots = (objspace->marked_slots * 2) / ((objspace->rincgc.pooled_slots / HEAP_OBJ_LIMIT) + 1);
+
+	if (0) fprintf(stderr, "objspace->marked_slots: %d, objspace->rincgc.pooled_page_num: %d, objspace->rincgc.step_slots: %d, \n",
+		       (int)objspace->marked_slots, (int)objspace->rincgc.pooled_slots, (int)objspace->rincgc.step_slots);
+#endif
 	objspace->flags.during_minor_gc = FALSE;
 	objspace->profile.major_gc_count++;
 	objspace->rgengc.remembered_wb_unprotected_objects = 0;
 	objspace->rgengc.old_objects = 0;
 	objspace->rgengc.last_major_gc = objspace->profile.count;
+	objspace->marked_slots = 0;
 	rgengc_mark_and_rememberset_clear(objspace, heap_eden);
     }
     else {
@@ -4879,6 +4900,7 @@ gc_marks_start(rb_objspace_t *objspace, https://github.com/ruby/ruby/blob/trunk/gc.c#L4900
 	rgengc_rememberset_mark(objspace, heap_eden);
     }
 #endif
+
     gc_mark_roots(objspace, NULL);
 
     gc_report(1, objspace, "gc_marks_start: (%s) end, stack in %d\n", full_mark ? "full" : "minor", (int)mark_stack_size(&objspace->mark_stack));
@@ -5026,6 +5048,9 @@ gc_marks_finish(rb_objspace_t *objspace) https://github.com/ruby/ruby/blob/trunk/gc.c#L5048
 	if (objspace->rgengc.old_objects > objspace->rgengc.old_objects_limit) {
 	    objspace->rgengc.need_major_gc |= GPR_FLAG_MAJOR_BY_OLDGEN;
 	}
+	if (RGENGC_FORCE_MAJOR_GC) {
+	    objspace->rgengc.need_major_gc = GPR_FLAG_MAJOR_BY_FORCE;
+	}
 
 	gc_report(1, objspace, "gc_marks_finish (marks %d objects, old %d objects, total %d slots, sweep %d slots, increment: %d, next GC: %s)\n",
 		  (int)objspace->marked_slots, (int)objspace->rgengc.old_objects, (int)heap->total_slots, (int)sweep_slots, (int)heap_allocatable_pages,
@@ -5049,6 +5074,7 @@ gc_marks_step(rb_objspace_t *objspace, i https://github.com/ruby/ruby/blob/trunk/gc.c#L5074
 	    gc_sweep(objspace);
 	}
     }
+    if (0) fprintf(stderr, "objspace->marked_slots: %d\n", (int)objspace->marked_slots);
 }
 
 static void
@@ -5098,7 +5124,7 @@ gc_marks_continue(rb_objspace_t *objspac https://github.com/ruby/ruby/blob/trunk/gc.c#L5124
 
 	if (slots > 0) {
 	    gc_report(2, objspace, "gc_marks_continue: provide %d slots from %s.\n", slots, from);
-	    gc_marks_step(objspace, slots);
+	    gc_marks_step(objspace, objspace->rincgc.step_slots);
 	}
 	else {
 	    gc_report(2, objspace, "gc_marks_continue: no more pooled pages (stack depth: %d).\n", (int)mark_stack_size(&objspace->mark_stack));

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]