[ltt-dev] [PATCH 06/10 round10] add LFHT_MEMORY_CHUNK low level memory management

Mathieu Desnoyers mathieu.desnoyers at efficios.com
Wed Nov 23 04:21:05 EST 2011


* Lai Jiangshan (laijs at cn.fujitsu.com) wrote:
> On 11/22/2011 06:20 PM, Mathieu Desnoyers wrote:
> > * Lai Jiangshan (laijs at cn.fujitsu.com) wrote:
> >> The old memory mangement is named as LFHT_MEMORY_ORDER.
> >>
> >> Signed-off-by: Lai Jiangshan <laijs at cn.fujitsu.com>
> >> ---
> >>  rculfhash.c |  116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
> >>  1 files changed, 111 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/rculfhash.c b/rculfhash.c
> >> index b7be893..ae1177f 100644
> >> --- a/rculfhash.c
> >> +++ b/rculfhash.c
> >> @@ -172,6 +172,10 @@
> >>  #define dbg_printf(fmt, args...)
> >>  #endif
> >>  
> >> +#if !defined(LFHT_MEMORY_ORDER) && !defined(LFHT_MEMORY_CHUNK)
> >> +#define LFHT_MEMORY_ORDER
> >> +#endif
> >> +
> >>  /*
> >>   * Split-counters lazily update the global counter each 1024
> >>   * addition/removal. It automatically keeps track of resize required.
> >> @@ -195,6 +199,8 @@
> >>  #define MAX_TABLE_ORDER			64
> >>  #endif
> >>  
> >> +#define MAX_CHUNK_TABLE			(1UL << 10)
> >> +
> >>  /*
> >>   * Minimum number of bucket nodes to touch per thread to parallelize grow/shrink.
> >>   */
> >> @@ -247,6 +253,7 @@ struct rcu_table {
> >>  	unsigned long resize_target;
> >>  	int resize_initiated;
> >>  
> >> +#ifdef LFHT_MEMORY_ORDER
> >>  	/*
> >>  	 * Contains the per order-index-level bucket node table. The size
> >>  	 * of each bucket node table is half the number of hashes contained
> >> @@ -255,6 +262,7 @@ struct rcu_table {
> >>  	 * levels to improve cache locality for small index orders.
> >>  	 */
> >>  	struct cds_lfht_node *tbl[MAX_TABLE_ORDER];
> >> +#endif
> >>  };
> >>  
> >>  /*
> >> @@ -289,6 +297,16 @@ struct cds_lfht {
> >>  	pthread_attr_t *resize_attr;	/* Resize threads attributes */
> >>  	long count;			/* global approximate item count */
> >>  	struct ht_items_count *split_count;	/* split item count */
> >> +
> >> +#ifdef LFHT_MEMORY_CHUNK
> >> +	/*
> >> +	 * Contains the bucket node chunks. The size of each bucket node
> >> +	 * chunk is ->min_alloc_size(avoid to alloc chunks with different
> >> +	 * size). chunks improve cache locality for small index orders
> >> +	 * and improve lookup_bucket() for the archs without hardware fls().
> >> +	 */
> >> +	struct cds_lfht_node *tbl[0];
> >> +#endif
> >>  };
> >>  
> >>  /*
> >> @@ -753,6 +771,93 @@ unsigned long _uatomic_xchg_monotonic_increase(unsigned long *ptr,
> >>  	return old2;
> >>  }
> >>  
> >> +#ifdef LFHT_MEMORY_CHUNK
> >> +static
> >> +struct cds_lfht *_cds_lfht_alloc(unsigned long min_alloc_size,
> >> +		unsigned long max_size)
> >> +{
> >> +	struct cds_lfht *ht;
> >> +
> >> +	min_alloc_size = max(min_alloc_size, max_size / MAX_CHUNK_TABLE);
> >> +	ht = calloc(1, sizeof(struct cds_lfht) +
> >> +			sizeof(ht->tbl[0]) * (max_size / min_alloc_size));
> > 
> > Hrm, this first level of indirection quickly becomes much larger than
> > the order-based table. Have you measured gains with this approach ?
> > 
> > Can you detail the use-case for this approach ?
> 
> I guess some times max_bucket_size/normal_bucket_size is not very high,
> (I also guess it is quit real/often in practice)
> so the users can use bigger min_alloc_size(bigger chunk size) and smaller
> chunk pointer table.
> 
> (see "History" of memory management)
> 
> > 
> > Have you measured the overhead of software fls() compared to the
> > overhead of increases cache footprint of the larger table for the
> > chunk-based approach ?
> 
> Sorry, I also guessed. So I just said this management is simpler and better
> when there is no hardware fls(). not "better performance", let the users
> make the decision.
> 
> It seems it is very hard to measure.
> 
> "History" of memory management:
> 
> I was thinking what is not good when this rculfhash is merged into linux kernel.
> the bigger order memory allocation will be an obstacle. we can not allocate
> big memory in kernel, we have to allocate small pieces(pages), and we have two
> choices:
> 1) (v)map the pages as continuous order memory.
> 2) use discontinuous pages as chunks.
> 
> 2) ===========> I got this LFHT_MEMORY_CHUNK.
> 
> 1) ===========> since we need to do mapping, why not map them all continuous,
> 		and map them when demanded, I got LFHT_MEMORY_RESERVED.
> 		(it introduces a new obstacle, we require big memory space,
> 		 but 64BITS can provide it easier.)

Ah, I see. So chunk on 32-bit (with page allocation), and reserved on
64-bit. Yep, this makes sense. So having these as plugins would be
really interesting.

Thanks,

Mathieu

> 
> The paper of Ori Shalev and Nir Shavit are actually a special LFHT_MEMORY_RESERVED.
> 
> 

-- 
Mathieu Desnoyers
Operating System Efficiency R&D Consultant
EfficiOS Inc.
http://www.efficios.com




More information about the lttng-dev mailing list