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

ruby-changes:42379

From: ko1 <ko1@a...>
Date: Thu, 31 Mar 2016 18:16:52 +0900 (JST)
Subject: [ruby-changes:42379] ko1:r54453 (trunk): * gc.c: change additional allocation policy.

ko1	2016-03-31 18:16:48 +0900 (Thu, 31 Mar 2016)

  New Revision: 54453

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

  Log:
    * gc.c: change additional allocation policy.
    
      Introduce new environement variable
      GC_HEAP_FREE_SLOTS_GOAL_RATIO (goal_ratio) to calculate the ratio
      of additional memory.
    
      Before this change, we add pages with the following formula
      (when free_slots < total_pages * RUBY_GC_HEAP_FREE_SLOTS_MIN_RATIO):
        next_pages = total_pages * RUBY_GC_HEAP_GROWTH_FACTOR
    
      This addition can allocate too much.
    
      With this change, we increase pages to satisfy the following formula:
        next_free_slots = next_total_slots * goal_ratio
      where
        next_free_slots = free_slots + adding_slots
        next_total_slots = total_slots + adding_slots.
    
      If you want to prepare many free slots, increase this ratio.
    
      If this variable is 0, then simply multiply
      RUBY_GC_HEAP_GROWTH_FACTOR.
    
    * gc.c (get_envparam_double): enable to accept 0.

  Modified files:
    trunk/ChangeLog
    trunk/gc.c
Index: gc.c
===================================================================
--- gc.c	(revision 54452)
+++ gc.c	(revision 54453)
@@ -118,10 +118,13 @@ rb_gc_guarded_ptr_val(volatile VALUE *pt https://github.com/ruby/ruby/blob/trunk/gc.c#L118
 #endif
 
 #ifndef GC_HEAP_FREE_SLOTS_MIN_RATIO
-#define GC_HEAP_FREE_SLOTS_MIN_RATIO 0.3
+#define GC_HEAP_FREE_SLOTS_MIN_RATIO  0.30
+#endif
+#ifndef GC_HEAP_FREE_SLOTS_GOAL_RATIO
+#define GC_HEAP_FREE_SLOTS_GOAL_RATIO 0.40
 #endif
 #ifndef GC_HEAP_FREE_SLOTS_MAX_RATIO
-#define GC_HEAP_FREE_SLOTS_MAX_RATIO 0.8
+#define GC_HEAP_FREE_SLOTS_MAX_RATIO  0.80
 #endif
 
 #ifndef GC_MALLOC_LIMIT_MIN
@@ -164,6 +167,7 @@ typedef struct { https://github.com/ruby/ruby/blob/trunk/gc.c#L167
     size_t growth_max_slots;
 
     double heap_free_slots_min_ratio;
+    double heap_free_slots_goal_ratio;
     double heap_free_slots_max_ratio;
     double oldobject_limit_factor;
 
@@ -1603,15 +1607,34 @@ heap_add_pages(rb_objspace_t *objspace, https://github.com/ruby/ruby/blob/trunk/gc.c#L1607
 static size_t
 heap_extend_pages(rb_objspace_t *objspace, size_t free_slots, size_t total_slots)
 {
-    size_t used = heap_allocated_pages - heap_tomb->total_pages;
-    size_t next_used_limit = (size_t)(used * gc_params.growth_factor);
+    double goal_ratio = gc_params.heap_free_slots_goal_ratio;
+    size_t used = heap_allocated_pages + heap_allocatable_pages;
+    size_t next_used;
+
+    if (goal_ratio == 0.0) {
+	next_used = (size_t)(used * gc_params.growth_factor);
+    }
+    else {
+	/* Find `f' where free_slots = f * total_slots * goal_ratio
+	 * => f = (total_slots - free_slots) / ((1 - goal_ratio) * total_slots)
+	 */
+	double f = (double)(total_slots - free_slots) / ((1 - goal_ratio) * total_slots);
+
+	if (f > gc_params.growth_factor) f = gc_params.growth_factor;
+	if (f < 1.0) f = 1.1;
+
+	next_used = (size_t)(f * used);
+
+	if (0) fprintf(stderr, "free_slots(%8ld)/total_slots(%8ld)=%1.2f, G(%1.2f), f(%1.2f), used(%8ld) => next_used(%8ld)\n",
+		       free_slots, total_slots, free_slots/(double)total_slots, goal_ratio, f, used, next_used);
+    }
 
     if (gc_params.growth_max_slots > 0) {
-	size_t max_used_limit = (size_t)(used + gc_params.growth_max_slots/HEAP_PAGE_OBJ_LIMIT);
-	if (next_used_limit > max_used_limit) next_used_limit = max_used_limit;
+	size_t max_used = (size_t)(used + gc_params.growth_max_slots/HEAP_PAGE_OBJ_LIMIT);
+	if (next_used > max_used) next_used = max_used;
     }
 
-    return next_used_limit - used;
+    return next_used - used;
 }
 
 static void
@@ -5424,7 +5447,6 @@ gc_marks_finish(rb_objspace_t *objspace) https://github.com/ruby/ruby/blob/trunk/gc.c#L5447
 	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,
 		  objspace->rgengc.need_major_gc ? "major" : "minor");
-
 #else /* USE_RGENGC */
 	if (sweep_slots < min_free_slots) {
 	    gc_report(1, objspace, "gc_marks_finish: heap_set_increment!!\n");
@@ -7299,7 +7321,7 @@ get_envparam_double(const char *name, do https://github.com/ruby/ruby/blob/trunk/gc.c#L7321
 	    if (RTEST(ruby_verbose)) fprintf(stderr, "invalid string for %s: %s\n", name, ptr);
 	    return 0;
 	}
-	if (val > lower_bound) {
+	if (val >= lower_bound) {
 	    if (RTEST(ruby_verbose)) fprintf(stderr, "%s=%f (default value: %f)\n", name, val, *default_value);
 	    *default_value = val;
 	    return 1;
@@ -7339,6 +7361,11 @@ gc_set_initial_pages(void) https://github.com/ruby/ruby/blob/trunk/gc.c#L7361
  * * RUBY_GC_HEAP_FREE_SLOTS_MIN_RATIO (new from 2.4)
  *   - Allocate additional pages when the number of free slots is
  *     lower than the value (total_slots * (this ratio)).
+ * * RUBY_GC_HEAP_FREE_SLOTS_GOAL_RATIO (new from 2.4)
+ *   - Allocate slots to satisfy this formula:
+ *       free_slots = total_slots * goal_ratio
+ *   - In other words, prepare (total_slots * goal_ratio) free slots.
+ *   - if this value is 0.0, then use RUBY_GC_HEAP_GROWTH_FACTOR directly.
  * * RUBY_GC_HEAP_FREE_SLOTS_MAX_RATIO (new from 2.4)
  *   - Allow to free pages when the number of free slots is
  *     greater than the value (total_slots * (this ratio)).
@@ -7385,6 +7412,7 @@ ruby_gc_set_params(int safe_level) https://github.com/ruby/ruby/blob/trunk/gc.c#L7412
     get_envparam_double("RUBY_GC_HEAP_GROWTH_FACTOR", &gc_params.growth_factor, 1.0);
     get_envparam_size  ("RUBY_GC_HEAP_GROWTH_MAX_SLOTS", &gc_params.growth_max_slots, 0);
     get_envparam_double("RUBY_GC_HEAP_FREE_SLOTS_MIN_RATIO", &gc_params.heap_free_slots_min_ratio, 0.1);
+    get_envparam_double("RUBY_GC_HEAP_FREE_SLOTS_GOAL_RATIO", &gc_params.heap_free_slots_goal_ratio, 0.0);
     get_envparam_double("RUBY_GC_HEAP_FREE_SLOTS_MAX_RATIO", &gc_params.heap_free_slots_max_ratio, 0.9);
     get_envparam_double("RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR", &gc_params.oldobject_limit_factor, 0.0);
 
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 54452)
+++ ChangeLog	(revision 54453)
@@ -1,3 +1,30 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Thu Mar 31 17:50:27 2016  Koichi Sasada  <ko1@a...>
+
+	* gc.c: change additional allocation policy.
+
+	  Introduce new environement variable
+	  GC_HEAP_FREE_SLOTS_GOAL_RATIO (goal_ratio) to calculate the ratio
+	  of additional memory.
+
+	  Before this change, we add pages with the following formula
+	  (when free_slots < total_pages * RUBY_GC_HEAP_FREE_SLOTS_MIN_RATIO):
+	    next_pages = total_pages * RUBY_GC_HEAP_GROWTH_FACTOR
+
+	  This addition can allocate too much.
+
+	  With this change, we increase pages to satisfy the following formula:
+	    next_free_slots = next_total_slots * goal_ratio
+	  where
+	    next_free_slots = free_slots + adding_slots
+	    next_total_slots = total_slots + adding_slots.
+
+	  If you want to prepare many free slots, increase this ratio.
+
+	  If this variable is 0, then simply multiply
+	  RUBY_GC_HEAP_GROWTH_FACTOR.
+
+	* gc.c (get_envparam_double): enable to accept 0.
+
 Thu Mar 31 17:48:25 2016  Koichi Sasada  <ko1@a...>
 
 	* gc.c (gc_marks_finish): fix syntax error.

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

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