Live data from Hacker News

All About Libpas, Phil's Super Fast Malloc

github.com

41–50 of 87 posts

Re: All About Libpas, Phil's Super Fast Malloc

#41
This looks awesome and I really like the tone of the documentation. Great work! At the same time I'm sort of worried, that such a deep change in the memory management of my day-to-day browser opens up a significant security risk for a considerable time, until new bugs are found and closed. I'm sure this got more than one pair of eyes at apple, but I'd really welcome a specific bug bounty on such a change...

Re: All About Libpas, Phil's Super Fast Malloc

#43

Earlier quoted context omitted.

I never got a chance to compare it to those, since I was most interested in beating bmalloc. And I mainly wanted to beat it on Safari workloads. I believe bmalloc was previously compared against jemalloc and tcmalloc, also using Safari workloads, and bmalloc was significantly faster at the time.

For other people who have never heard of bmalloc - it's a custom allocator used only by WebKit. I guess it's not surprising they added one since the Mac system allocator is extremely slow. A custom allocator is pretty much a free 20% speed up on Mac (depending on your workload) but I found they made no difference on Linux. Haven't tried on Windows.

Alas, many people think performance engineering is only about the wall clock time of their program and not what impact it has on anything else.

malloc performance highly depends on how large the allocations are though.

Re: All About Libpas, Phil's Super Fast Malloc

#44

General purpose memory-allocation is a lie. Everything has use cases where they're faster than other libraries. I think that's why we keep seeing newer malloc schemes pop up, because the performance of the heap 100% depends on the use-case, and different people have different use cases. Still, studying everyone else's heaps (and garbage collectors, a closely related discussion) is probably good for high-performance p…

I've seen a few opensource projects archive their custom allocators because they were not beating the system's one or jemalloc. So if you have the skill and time then yeah go for it, else stick with general purpose ones.

Its very easy to beat the general purpose ones if you know your exact use case.

Ex: 16-bit pointers is a 65536-sized heap. Assume 8-bytes per element, that's 512KB of space. A bit small, but large enough to so a lot of things.

65536 elements can be represented as a bitmask. The bitmask only takes up 8192-bytes (8KB), which fits inside of 16 AVX512 registers (Intel offers 32x AVX512/ZMM registers btw). Or it fits inside of GPU __shared__ memory.

If you need multithreaded, you perform atomic AND and atomic OR to clear, and set, the bitmask as appropriate.

-------

Do you know the exact size of your heap? The size of the pointer? The amount of parallelism involved? What about the size of the elements? Access pattern? (Bump-alloc'd Linked Lists are a sequential traversal over RAM btw, so that's very efficient), etc. etc.

The 64-bit pointer is overkill for most people's purposes. 32-bits represents 4-billion objects, and if each object is 16-bytes long that's 64GBs of RAM. Right here right now, a 32-bit pointer / custom allocator already offers many benefits over the 64-bit pointer. (half-sized pointers, more data in cache, etc. etc.)

Re: All About Libpas, Phil's Super Fast Malloc

#45

I admit I'm a sucker for metacircularity, but have to ask: > The bootstrap heap has hacks to allow itself to allocate that array out of itself. Not quite following that, can someone elaborate?

I suspect its that - generally when you write a heap it needs to keep some metadata. if you have a multi-heap system (really handy), then its generally easier to host that metadata on another heap. sometimes you really want that, because the target heap might be specialized for different kinds of data. so I assume this is carefully constructing the heap state so that it can be used for its own metadata as its being constructed

Re: All About Libpas, Phil's Super Fast Malloc

#46
Are there any projects that surgically augment the memory APIs to be more cooperative? Sure `malloc` implementations will make various tradeoffs, but what if the malloc/free APIs were expanded to expose more programmer-intent or cooperative defrag, etc?

- Perhaps `malloc` could ask for an intended lifecycle (think GC generation) that could swap arenas or other algo internals. This opens us up to meta-allocators.

- Perhaps program lifecycle hooks that give allocators more context into how already-allocated memory intends to be accessed. ("Done bootstrapping the server, so now new memory will be accessed by single threads and only live for one request", etc)

- Perhaps the programmer could periodically call `remalloc` to allow objects to be moved or promoted between arenas/generations.

- Perhaps mallocs/frees could be more intelligently batched (where explicit structs/arrays don't normally make sense) for surprise-free defrag or OS allocation.

- Intelligent pairing of malloc/free with explicit notions of intended re-use; some indication of "I will free this and ask for the same memory again in the same call" or auto-struct-ing mallocs which know that we tend stack malloc(foo);malloc(bar);free(bar);free(foo). Avoid any actual OS/memory involvement whatsoever.

- Perhaps `identmalloc` could handle common flyweight patterns of instantiate-unless-exists; e.g. intelligently turn shared state into offsets into a contiguous arenas. This may be more useful in C++ with existing conventions around copy-by-value constructs.

Some of these are indeed components of existing mallocs/allocators (e.g. libpas is type-aware), but my point is that allocators have to jump through hoops to derive heuristics, and these heuristics often amount to "the programmer often intends to use memory like X." Performance engineers then pattern-match for X rather than cooperating with the compiler to expose X intrinsically from the beginning. The above ideas impose slightly different programming paradigms, so there's still the white wale of a perfect drop-in heuristic, but it seems less subject to temporary or local maxima.

So: Are there compelling (albeit slightly less general-purpose) alternatives where the allocator and programmer communicate additional hints or other API contracts that allow the allocator to move away from heuristics and into proven patterns? Or is this basically akin to "use c++/smart pointers or just get a gc"?

Re: All About Libpas, Phil's Super Fast Malloc

#49

Earlier quoted context omitted.

I never got a chance to compare it to those, since I was most interested in beating bmalloc. And I mainly wanted to beat it on Safari workloads. I believe bmalloc was previously compared against jemalloc and tcmalloc, also using Safari workloads, and bmalloc was significantly faster at the time.

For other people who have never heard of bmalloc - it's a custom allocator used only by WebKit. I guess it's not surprising they added one since the Mac system allocator is extremely slow. A custom allocator is pretty much a free 20% speed up on Mac (depending on your workload) but I found they made no difference on Linux. Haven't tried on Windows.

What's the workload where you found that to be the case? The system allocator is heavily tuned for general use, and should be very difficult to beat -- generally.

Re: All About Libpas, Phil's Super Fast Malloc

#50

Earlier quoted context omitted.

I think in either case, GC or not, you write something intuitively and then when it becomes an actual problem, you study the patterns and improve them, but most of the time you can leave it alone and the general purpose thing is good enough. Or if you are in a niche like audio/video or something, you avoid allocations all together during the bulk of the code.

Oh for sure. Premature optimizing is usually bad form. What is tricky about performance issues in allocation is that they can be hard to profile. There are tools for analyzing GC performance in GC'd languages, but sometimes malloc/free can just be a big black box.

Premature optimization is not bad form when it's re-framed as good architecture. So it's not 'usually bad form' to architect something from the outset, using your experience, and that's something everyone understands. This pervasive disdain for premature optimization leads to bad architecture that often leads to expensive rewrites. So because the word optimization is so overloaded and treated with disdain it feels like we need a new language to talk about what's really meant by 'premature optimization' ( the bad kind)
Post reply on HN