[PATCH v4 4/7] malloc: add tcache support for large chunk caching
Cupertino Miranda
cupertino.miranda@oracle.com
Mon Mar 17 12:25:47 GMT 2025
On 15-03-2025 00:02, DJ Delorie wrote:
> Cupertino Miranda <cupertino.miranda@oracle.com> writes:
>> Existing tcache implementation in glibc seems to focus in caching
>> smaller data size allocations, limiting the size of the allocation to
>> 1KB.
>
> Statistics at that time showed that such packets were by far the most
> popular ones to allocate.
No doubts, I do give some more context below for why I did this work.
>
>> This patch changes tcache implementation to allow to cache any chunk
>> size allocations. The implementation adds extra bins (linked-lists)
>> which store chunks with different ranges of allocation sizes. Bin
>> selection is done in multiples in powers of 2 and chunks are inserted in
>> growing size ordering within the bin. The last bin contains all other
>> sizes of allocations.
>
> I fear this will cause fragmentation and thus higher VSS usage. I've
> already seen proposals for changes in tcache to try to reduce the
> fragmentation it's already causing. Do you have any benchmarks on
> memory *usage* changes with this patch? It would have to be a fairly
> complex application.
Please notice that without setting glibc.malloc.tcache_max the semantics
of tcache are kept to original behaviour.
Last week, I worked on collecting data with mimalloc-bench, in the
context of a few reviews from Wilco Dijkstra which shown some
performance degradation.
Within those I have collected the data without setting
glibc.malloc.tcache_max tunable, which implied that only up to ~1k
chunks would be cached.
Considering that semantically tcaches work in same way as before, I did
not care to make any memory comparisons, as any variation would be
unrelated to the patch series.
However, our original bench-marking has been with MySQL application,
which historically with glibc malloc uses huge amounts of VSS and with
time slowly but steadily consumes RSS until the process gets killed.
The presented patch allows within MySQL application to set max_arena=1
and keep performance levels by calibrating tcache_max tunable to a big
enough value.
Without tcache_max tunable performance would drop to half.
Doing this VSS is kept to a minimum and also RSS stops growing.
I have provided MySQL charts as a reply the initial RFC of the patch series.
>
>
>> /* We want 64 entries. This is an arbitrary limit, which tunables can reduce. */
>> +# define TCACHE_UNBOUND_SIZE_BINS 10
>> # define TCACHE_MAX_BINS 64
>
> Putting the new line there means the comment no longer makes sense ;-)
Will rewrite comment here.
>
>> # define MAX_TCACHE_SIZE tidx2usize (TCACHE_MAX_BINS-1)
>> +# define TCACHE_FIXED_SIZE_BINS \
>> + (mp_.tcache_bins < TCACHE_MAX_BINS ? mp_.tcache_bins : TCACHE_MAX_BINS)
>
> I can see this adding a lot of logic to tcache. Do the benchmarks
> indicate it's faster?
In v4, yes.
>
>> /* Only used to pre-fill the tunables. */
>> -# define tidx2usize(idx) (((size_t) idx) * MALLOC_ALIGNMENT + MINSIZE - SIZE_SZ)
>> +# define tidx2usize(idx) (((size_t) idx) * MALLOC_ALIGNMENT + MINSIZE - MALLOC_ALIGNMENT + 1)
>
> This seems unrelated. Has this been verified on a platform where you
> know SIZE_SZ is different than MALLOC_ALIGNMENT+1 ?
I am not sure if CI for glibc is running in such platforms. It passed
everything, AFAIK. If not then, no.
BTW, I just reversed the equation for csize2tidx. This seemed more
accurate. Maybe it is wrong! :(
>
>> ,
>> .tcache_count = TCACHE_FILL_COUNT,
>> .tcache_bins = TCACHE_MAX_BINS,
>> - .tcache_max_bytes = tidx2usize (TCACHE_MAX_BINS-1),
>> + .tcache_max_bytes = MAX_TCACHE_SIZE,
>> - .tcache_unsorted_limit = 0 /* No limit. */
>> + .tcache_unsorted_limit = 0, /* No limit. */
>> };
>
> Do we really need the extra comma here?
No!
>
>> - for (i = 0; i < TCACHE_MAX_BINS; ++i)
>> + for (i = 0; i < mp_.tcache_bins; ++i)
>
> This is wrong if the number of bins can be changed during program
> execution; the intent is to flush the WHOLE cache, not the CURRENT
> cache.
Right! Should change it. However to (TCACHE_MAX_BINS +
TCACHE_UNBOUND_SIZE_BINS).
Thanks,
Cupertino
More information about the Libc-alpha
mailing list