jemalloc 3 performance vs. mozjemalloc
Daniel Micay
danielmicay at gmail.com
Tue Feb 3 15:25:11 PST 2015
On 03/02/15 05:51 PM, Mike Hommey wrote:
> Hi,
>
> I've been tracking a startup time regression in Firefox for Android when
> we tried to switch from mozjemalloc (memory refresher: it's derived from
> jemalloc 0.9) to mostly current jemalloc dev.
>
> It turned out to be https://github.com/jemalloc/jemalloc/pull/192 but in
> the process I found a few interesting things that I thought are worth
> mentioning:
>
> - Several changesets between 3.6 and current dev made the number of
> instructions as reported by perf stat on GNU/Linux x86-64 increase
> significantly, on a ~200k alloc/dealloc testcase that does nothing
> else[1]:
> - 5460aa6f6676c7f253bfcb75c028dfd38cae8aaf made the count go from
> 69M to 76M.
> - 6ef80d68f092caf3b3802a73b8d716057b41864c from 76M to 81.5M
> - 4dcf04bfc03b9e9eb50015a8fc8735de28c23090 from 81.5M to 85M
> - 155bfa7da18cab0d21d87aa2dce4554166836f5d from 85M to 88M
> I didn't investigate further because it was a red herring as far as
> the regression I was tracking was concerned.
>
> - The average number of mutex lock per alloc/dealloc is close to 1 with
> mozjemalloc (1.001), but 1.13 with jemalloc 3 (same testcase as above).
> Fortunately, contention is likely lower (I measured it to be lower, but
> the instrumentation had so much overhead that it may have skewed the
> results), but pthread_mutex_lock/unlock are not free as far as
> instruction count is concerned.
>
> Cheers,
>
> Mike
You can speed up locking/unlocking by ~10-20% by dropping a lighter
mutex implementation. Here's a simple C11 implementation based on
Drepper's futex paper, for example:
https://github.com/thestinger/allocator/blob/master/mutex.h
https://github.com/thestinger/allocator/blob/master/mutex.c
It would be easy enough to add (adaptive) spinning to lock/unlock just
like the glibc adaptive mutex that's currently used by jemalloc.
Implementing great load balancing for arenas would greatly reduce the
benefits of fine-grained locking. The best approach that I've come up
with is the following:
* 1 arena per core, rather than 4 arenas per core
* assign the initial threads via round-robin, until each arena is used
* when there are no unused arenas, switch to sched_getcpu()
* store the thread ID of the last thread to allocate in the arena
The algorithm for picking an arena for allocating:
if thread.last_arena.last_allocator == thread.id && trylock() != fail
pass
else:
pick_arena_with_sched_getcpu()
lock()
set_last_allocator()
This results in significantly better load balancing than jemalloc has at
the moment while using 1/4 as many arenas.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://jemalloc.net/mailman/jemalloc-discuss/attachments/20150203/7cf28004/attachment.sig>
More information about the jemalloc-discuss
mailing list