Add RUBY_GC_HEAP_INIT_SIZE_%d_SLOTS to pre-init pools granularly
The old RUBY_GC_HEAP_INIT_SLOTS isn't really usable anymore as it initalize all the pools by the same factor, but it's unlikely that pools will need similar sizes. In production our 40B pool is 5 to 6 times bigger than our 80B pool.
This commit is contained in:
parent
6e7990144f
commit
3ab3455145
Notes:
git
2023-02-08 08:26:29 +00:00
24
gc.c
24
gc.c
@ -11749,15 +11749,28 @@ get_envparam_double(const char *name, double *default_value, double lower_bound,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gc_set_initial_pages(rb_objspace_t *objspace)
|
gc_set_initial_pages(rb_objspace_t *objspace, int global_heap_init_slots)
|
||||||
{
|
{
|
||||||
gc_rest(objspace);
|
gc_rest(objspace);
|
||||||
|
|
||||||
for (int i = 0; i < SIZE_POOL_COUNT; i++) {
|
for (int i = 0; i < SIZE_POOL_COUNT; i++) {
|
||||||
rb_size_pool_t *size_pool = &size_pools[i];
|
rb_size_pool_t *size_pool = &size_pools[i];
|
||||||
|
char env_key[sizeof("RUBY_GC_HEAP_INIT_SIZE_" "_SLOTS") + DECIMAL_SIZE_OF_BITS(sizeof(size_pool->slot_size) * CHAR_BIT)];
|
||||||
|
snprintf(env_key, sizeof(env_key), "RUBY_GC_HEAP_INIT_SIZE_%d_SLOTS", size_pool->slot_size);
|
||||||
|
|
||||||
if (gc_params.heap_init_slots > size_pool->eden_heap.total_slots) {
|
size_t pool_init_slots = 0;
|
||||||
size_t slots = gc_params.heap_init_slots - size_pool->eden_heap.total_slots;
|
if (!get_envparam_size(env_key, &pool_init_slots, 0)) {
|
||||||
|
if (global_heap_init_slots) {
|
||||||
|
// If we use the global init slot we ponderate it by slot size
|
||||||
|
pool_init_slots = gc_params.heap_init_slots / (size_pool->slot_size / BASE_SLOT_SIZE);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pool_init_slots > size_pool->eden_heap.total_slots) {
|
||||||
|
size_t slots = pool_init_slots - size_pool->eden_heap.total_slots;
|
||||||
int multiple = size_pool->slot_size / BASE_SLOT_SIZE;
|
int multiple = size_pool->slot_size / BASE_SLOT_SIZE;
|
||||||
size_pool->allocatable_pages = slots * multiple / HEAP_PAGE_OBJ_LIMIT;
|
size_pool->allocatable_pages = slots * multiple / HEAP_PAGE_OBJ_LIMIT;
|
||||||
}
|
}
|
||||||
@ -11823,7 +11836,10 @@ ruby_gc_set_params(void)
|
|||||||
|
|
||||||
/* RUBY_GC_HEAP_INIT_SLOTS */
|
/* RUBY_GC_HEAP_INIT_SLOTS */
|
||||||
if (get_envparam_size("RUBY_GC_HEAP_INIT_SLOTS", &gc_params.heap_init_slots, 0)) {
|
if (get_envparam_size("RUBY_GC_HEAP_INIT_SLOTS", &gc_params.heap_init_slots, 0)) {
|
||||||
gc_set_initial_pages(objspace);
|
gc_set_initial_pages(objspace, TRUE);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
gc_set_initial_pages(objspace, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
get_envparam_double("RUBY_GC_HEAP_GROWTH_FACTOR", &gc_params.growth_factor, 1.0, 0.0, FALSE);
|
get_envparam_double("RUBY_GC_HEAP_GROWTH_FACTOR", &gc_params.growth_factor, 1.0, 0.0, FALSE);
|
||||||
|
@ -550,7 +550,12 @@ There are currently 4 possible areas where the GC may be tuned by
|
|||||||
the following 11 environment variables:
|
the following 11 environment variables:
|
||||||
.Bl -hang -compact -width "RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR"
|
.Bl -hang -compact -width "RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR"
|
||||||
.It Ev RUBY_GC_HEAP_INIT_SLOTS
|
.It Ev RUBY_GC_HEAP_INIT_SLOTS
|
||||||
Initial allocation slots. Introduced in Ruby 2.1, default: 10000.
|
Initial allocation slots. Applies to all slot sizes. Introduced in Ruby 2.1, default: 10000.
|
||||||
|
.Pp
|
||||||
|
.It Ev RUBY_GC_HEAP_INIT_SIZE_%d_SLOTS
|
||||||
|
Initial allocation of slots in a specific size pool.
|
||||||
|
The available size pools can be found in `GC.stat_heap`.
|
||||||
|
Introduced in Ruby 3.3.
|
||||||
.Pp
|
.Pp
|
||||||
.It Ev RUBY_GC_HEAP_FREE_SLOTS
|
.It Ev RUBY_GC_HEAP_FREE_SLOTS
|
||||||
Prepare at least this amount of slots after GC.
|
Prepare at least this amount of slots after GC.
|
||||||
|
@ -315,6 +315,21 @@ class TestGc < Test::Unit::TestCase
|
|||||||
}
|
}
|
||||||
assert_normal_exit("exit", "[ruby-core:39777]", :child_env => env)
|
assert_normal_exit("exit", "[ruby-core:39777]", :child_env => env)
|
||||||
|
|
||||||
|
env = {}
|
||||||
|
GC.stat_heap.each do |_, s|
|
||||||
|
env["RUBY_GC_HEAP_INIT_SIZE_#{s[:slot_size]}_SLOTS"] = "200000"
|
||||||
|
end
|
||||||
|
assert_normal_exit("exit", "", :child_env => env)
|
||||||
|
|
||||||
|
env["RUBY_GC_HEAP_INIT_SLOTS"] = "100000"
|
||||||
|
assert_normal_exit("exit", "", :child_env => env)
|
||||||
|
|
||||||
|
env = {}
|
||||||
|
GC.stat_heap.each do |_, s|
|
||||||
|
env["RUBY_GC_HEAP_INIT_SIZE_#{s[:slot_size]}_SLOTS"] = "0"
|
||||||
|
end
|
||||||
|
assert_normal_exit("exit", "", :child_env => env)
|
||||||
|
|
||||||
env = {
|
env = {
|
||||||
"RUBYOPT" => "",
|
"RUBYOPT" => "",
|
||||||
"RUBY_GC_HEAP_INIT_SLOTS" => "100000"
|
"RUBY_GC_HEAP_INIT_SLOTS" => "100000"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user