From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp41.i.mail.ru (smtp41.i.mail.ru [94.100.177.101]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 3E32445C304 for ; Sun, 20 Dec 2020 21:31:48 +0300 (MSK) References: <536b26064e5db03e348d93f2b70d86ee0a474db3.1608282196.git.mechanik20051988@gmail.com> From: Vladislav Shpilevoy Message-ID: <7cb66637-2ad5-9218-c723-8b67fbe184cd@tarantool.org> Date: Sun, 20 Dec 2020 19:31:42 +0100 MIME-Version: 1.0 In-Reply-To: <536b26064e5db03e348d93f2b70d86ee0a474db3.1608282196.git.mechanik20051988@gmail.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Subject: Re: [Tarantool-patches] [PATCH 3/3] Changed small allocator pool management List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: mechanik20051988 , tarantool-patches@dev.tarantool.org Thanks for the patch! See 4 comments below. On 18.12.2020 14:35, mechanik20051988 wrote: > From: mechanik20051988 > > In previous version allocator create new pool if necessary > and insert it in the pools tree. Now we allocate pools on 1. create -> created, insert -> inserted. > the stage of allocator creation according alloc_factor. > We use small_alloc class for this purpose also we use it > to find necessary pool when we alloc memory. This is faster > then previous allocator behavior and also fixes #5216. > > Closes #5216 > --- > small/small.c | 212 ++++++++++++-------------------------------------- > small/small.h | 47 ++++------- > 2 files changed, 62 insertions(+), 197 deletions(-) > > diff --git a/small/small.c b/small/small.c > index 48085fb..2196906 100644 > --- a/small/small.c > +++ b/small/small.c > @@ -102,53 +70,17 @@ small_alloc_create(struct small_alloc *alloc, struct slab_cache *cache, > { > alloc->cache = cache; > /* Align sizes. */ > - objsize_min = small_align(objsize_min, STEP_SIZE); > - alloc->step_pool0_step_count = (objsize_min - 1) >> STEP_SIZE_LB; > + objsize_min = small_align(objsize_min, sizeof(intptr_t)); > /* Make sure at least 4 largest objects can fit in a slab. */ > alloc->objsize_max = > mempool_objsize_max(slab_order_size(cache, cache->order_max)); > > - if (!(alloc->objsize_max > objsize_min + STEP_POOL_MAX * STEP_SIZE)) { > - fprintf(stderr, "Can't create small alloc, small " > - "object min size should not be greather than %u\n", > - alloc->objsize_max - (STEP_POOL_MAX + 1) * STEP_SIZE); > - abort(); > - } > + assert(alloc_factor > 1. && alloc_factor <= 2.); > > - struct mempool *step_pool; > - for (step_pool = alloc->step_pools; > - step_pool < alloc->step_pools + STEP_POOL_MAX; > - step_pool++) { > - mempool_create(step_pool, alloc->cache, objsize_min); > - objsize_min += STEP_SIZE; > - } > - alloc->step_pool_objsize_max = (step_pool - 1)->objsize; > - if (alloc_factor > 2.0) > - alloc_factor = 2.0; > - /* > - * Correct the user-supplied alloc_factor to ensure that > - * it actually produces growing object sizes. > - */ > - if (alloc->step_pool_objsize_max * alloc_factor < > - alloc->step_pool_objsize_max + STEP_SIZE) { > - > - alloc_factor = > - (alloc->step_pool_objsize_max + STEP_SIZE + 0.5)/ > - alloc->step_pool_objsize_max; > - } > alloc->factor = alloc_factor; > - > - /* Initialize the factored pool cache. */ > - struct factor_pool *factor_pool = alloc->factor_pool_cache; > - do { > - factor_pool->next = factor_pool + 1; > - factor_pool++; > - } while (factor_pool != > - alloc->factor_pool_cache + FACTOR_POOL_MAX - 1); > - factor_pool->next = NULL; > - alloc->factor_pool_next = alloc->factor_pool_cache; > - factor_tree_new(&alloc->factor_pools); > - (void) factor_pool_create(alloc, NULL, alloc->objsize_max); > + small_class_create(&alloc->small_class, sizeof(intptr_t), > + alloc->factor, objsize_min); 2. Broken alignment. > + factor_pool_create(alloc); > > lifo_init(&alloc->delayed); > lifo_init(&alloc->delayed_large); > @@ -360,16 +244,16 @@ mempool_iterator_create(struct mempool_iterator *it, > struct small_alloc *alloc) > { > it->alloc = alloc; > - it->step_pool = alloc->step_pools; > - factor_tree_ifirst(&alloc->factor_pools, &it->factor_iterator); > + it->factor_iterator = 0; > } > > struct mempool * > mempool_iterator_next(struct mempool_iterator *it) > { > - if (it->step_pool < it->alloc->step_pools + STEP_POOL_MAX) > - return it->step_pool++; > - struct factor_pool *factor_pool = factor_tree_inext(&it->factor_iterator); > + struct factor_pool *factor_pool = NULL; > + if (it->factor_iterator < it->alloc->factor_pool_cache_size) > + factor_pool = > + &it->alloc->factor_pool_cache[(it->factor_iterator)++]; 3. When 'if' body has more than 1 line, it must be in {}. > if (factor_pool) { > return &(factor_pool->pool); > } > @@ -387,7 +271,7 @@ small_alloc_destroy(struct small_alloc *alloc) > mempool_destroy(pool); > } > lifo_init(&alloc->delayed); > - > + alloc->factor_pool_cache_size = 0; 4. Why is it needed at destruction? > /* Free large allocations */ > void *item; > while ((item = lifo_pop(&alloc->delayed_large))) {