Live data from Hacker News

All About Libpas, Phil's Super Fast Malloc

github.com

11–20 of 87 posts

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

#12

I'm always suspicious of things that are named after the maker.

Like Linux, or gcc.godbolt.org?

I kid, but I don't see it as a downside for software. Naming a scientific phenomenon after yourself is a red flag though, see also the Crackpot Index [1].

[1]: https://math.ucr.edu/home/baez/crackpot.html

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

#15

Trying to understand the license for bmalloc, and webkit in general. The WebCore folder has an Apple license and two LGPL licenses. The root folder has no license file. Can anyone comment?

libpas is BSD 2-clause. so is bmalloc. libpas is in the bmalloc directory in WebKit, but is really a separate piece of code.

each file has its own license header.

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

#16
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 programmers.

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

#17

> Consequently, passing a function pointer (or struct of function pointers), where the pointer points to an always_inline function and the callee is always_inline results in specialization akin to template monomorphization. This works to any depth; the compiler won't be satisfied until there are no more always_inline function calls. This fortuitous development in compilers allowed me to write very nice template code…

I still don't quite understand how the technique saves code size versus C++ templates, although I am quite eager to understand it since template instantiation is a thorn in my side when writing code for a microcontroller with 32KB of code space.

Is the idea that the struct contains pointers to always_inline functions, and that the compiler has visibility into this at the top of the always_inline call stack, so the always_inline gets monomorphized even through multiple layers of pointer indirection? If I'm understanding it right, that's a pretty nice technique. Would this allow you to mark a "class" (or individual members of that class) as "hot, please monomorphize" by making it always_inline, or "cold, please use regular pointers" by omitting always_inline?

C++ templates would force you to monomorphize every variant, or use vtables (function pointers) for every variant, without the ability to choose the approach for each subclass. The compiler is also spectacularly bad at recognizing deduplication opportunities between template specializations.

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

#18

> Consequently, passing a function pointer (or struct of function pointers), where the pointer points to an always_inline function and the callee is always_inline results in specialization akin to template monomorphization. This works to any depth; the compiler won't be satisfied until there are no more always_inline function calls. This fortuitous development in compilers allowed me to write very nice template code…

I still don't quite understand how the technique saves code size versus C++ templates, although I am quite eager to understand it since template instantiation is a thorn in my side when writing code for a microcontroller with 32KB of code space. Is the idea that the struct contains pointers to always_inline functions, and that the compiler has visibility into this at the top of the always_inline call stack, so the al…

> Would this allow you to mark a "class" (or individual members of that class) as "hot, please monomorphize" by making it always_inline, or "cold, please use regular pointers" by omitting always_inline?

From my understanding of the technique, this is correct.

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

#19

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…

Yeah, you're totally right.

Libpas beats other mallocs in WebKit. I also had benchmarks involving non-WebKit workloads and the results were all over the place (sometimes slower than other mallocs by a lot, sometimes faster by a lot - same thing with memory, sometimes more efficient, sometimes less). This didn't surprise me; I've seen this before when writing memory management code.

I think it makes sense for large software projects that use malloc a lot and care about perf to eventually either write their own malloc or to take an existing one and then tune it a lot.

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

#20

> Consequently, passing a function pointer (or struct of function pointers), where the pointer points to an always_inline function and the callee is always_inline results in specialization akin to template monomorphization. This works to any depth; the compiler won't be satisfied until there are no more always_inline function calls. This fortuitous development in compilers allowed me to write very nice template code…

I still don't quite understand how the technique saves code size versus C++ templates, although I am quite eager to understand it since template instantiation is a thorn in my side when writing code for a microcontroller with 32KB of code space. Is the idea that the struct contains pointers to always_inline functions, and that the compiler has visibility into this at the top of the always_inline call stack, so the al…

I think that's right.

C++ binaries tend to be pretty large because they use templates/monomorphization a lot, even when there aren't really meaningful performance gains. For example, it often doesn't make sense to have 20 instantiations of std::vector, when only two of them are used in the critical path. Rust can be even further in this unfortunate direction because of the borrow checker's restrictions around polymorphism and abstraction.

In comparison, C, Java, and Javascript tend to rely on dynamic dispatch more often (not that C has any built-in dynamic dispatch features, but in practice, C programs tend to use function pointers manually).

A few languages like C# have a really nice balance, and monomorphize in the JIT at run-time.

With this technique they mention, C is the only mainstream language I know of that lets you control it in a decoupled way, which is really cool.

Post reply on HN