Live data from Hacker News

Make Ubuntu packages 90% faster by rebuilding them

gist.github.com

251–260 of 375 posts

Re: Make Ubuntu packages 90% faster by rebuilding them

#251

"Make one Ubuntu package 90% faster by rebuilding it and switching the memory allocator" i wish i could slap people in the face over standard tcp/ip for clickbait. it was ONE package and some gains were not realized by recompilation. i have to give it to him, i have preloaded jemalloc to one program to swap malloc implementation and results have been very pleasant. not in terms of performance (did not measure) but in…

To me it's obviously a scam because there's no way such an improvement can be achieved globally with a single post explanation. 90% faster is a micro-benchmark number.

True that, I mean it is still interesting, that if you have a narrow task, you might achieve some significant speed up from rebuilding them. But this is a very niche application.

Re: Make Ubuntu packages 90% faster by rebuilding them

#252

Earlier quoted context omitted.

> This just simply is not something these allocators suffer from and would be major bugs the projects would solve. Not OP, but the following logic shows why this claim is bogus. In short: If two non-garbage-collecting memory allocators do anything differently -- other than behave as perfect "mirror images" of each other, so that whenever one allocates byte i, the other allocates byte totalMem-i -- then there exists a…

I really have no idea what you’re getting at here. This isn’t embedded where there’s a fixed pool to allocate out of. If there’s insufficient space it’ll get more virtual memory from the OS. Also, nothing you’ve said actually says that the other allocator will be the worse one. Indeed, glibc is known to hold onto memory longer and have more fragmentation than allocators like mimalloc and tcmalloc so I’m still at a lo…

> If there’s insufficient space it’ll get more virtual memory from the OS.

Swap space is finite too.

> Also, nothing you’ve said actually says that the other allocator will be the worse one.

I'm not claiming that either is worse. I'm showing mathematically that for any two allocators that behave differently at all (with the one tiny exception of a pair of allocators that are perfect mirror images of each other), it's possible to craft a program that succeeds on one but fails on the other.

I didn't say so explicitly as I thought it was obvious, but the upshot is: It's never completely safe to just change the allocator. Even if 99% if the time, one works better than the other, there's provably a corner case where it will fail but the other does not.

Re: Make Ubuntu packages 90% faster by rebuilding them

#253

I wonder why my brain calculates `90% faster' as 10% of the time (i.e. t1=0.1*t0) it used to be working. However, this makes sense only if we calculate the recompiled application running time as t1=t0/1.90

"by 190%" instead of "90% faster" is far clearer.

Re: Make Ubuntu packages 90% faster by rebuilding them

#254
post #215
post #190

He is still missing profile guided optimizations (with his testcase), and bolt. And in some/most cases -Os is faster than -O3 Boehm GC is usually slower than glibc with lots of allocs. MPS would be better, but needs lots of rewriting. https://github.com/Ravenbrook/mps

> And in some/most cases -Os is faster than -O3 This surprises me. Can you please elaborate?

If the whole program can fit in the L1/L2 cache, it can speed up things quite a lot!

Re: Make Ubuntu packages 90% faster by rebuilding them

#255

"Make one Ubuntu package 90% faster by rebuilding it and switching the memory allocator" i wish i could slap people in the face over standard tcp/ip for clickbait. it was ONE package and some gains were not realized by recompilation. i have to give it to him, i have preloaded jemalloc to one program to swap malloc implementation and results have been very pleasant. not in terms of performance (did not measure) but in…

I did research into the glibc memory allocator. Turns out this is not memory fragmentation, but per-thread caches that are never freed back to the kernel! A free() call does not actually free the memory externally unless in exceptional circumstances. The more threads and CPU cores you have, the worse this problem becomes. One easy solution is setting the "magic" environment variable MALLOC_ARENA_MAX=2, which limits t…

The glibc memory allocator DOES have pathological cases that lead to what can look like memory leaks. See https://glandium.org/blog/?p=3698 https://glandium.org/blog/?p=3723 https://sourceware.org/bugzilla/show_bug.cgi?id=23416 (despite being rather old, it's also still a problem)

Re: Make Ubuntu packages 90% faster by rebuilding them

#256
In the late 1990s, the most common method for distributing a package was by providing its source code as a tarball. You essentially had to run ./configure and make on every package. I believe ./configure does some of what the OP did in a clever way, checking for locally installed alternatives, etc. It’s still pretty cool, though. I didn’t think a malloc replacement would significantly improve performance.

Re: Make Ubuntu packages 90% faster by rebuilding them

#257
post #245

Earlier quoted context omitted.

More than that, based on the basic architecture of JEmalloc, mimalloc and tcmalloc, you should always expect their fragmentation behavior to be better for long-running software than the glibc malloc. (At the expense of consuming substantially more memory for very small programs with only a few allocations of a given size). The glibc malloc has nearly pessimal fragmentation behavior, you are very confused here.

> you are very confused here Is this addressed to me? If so would you do me the kindness of attempting to disabuse me of my confusion?

Wait, no, sorry. That reply was supposed to go to a different post.

Re: Make Ubuntu packages 90% faster by rebuilding them

#259

Earlier quoted context omitted.

I really have no idea what you’re getting at here. This isn’t embedded where there’s a fixed pool to allocate out of. If there’s insufficient space it’ll get more virtual memory from the OS. Also, nothing you’ve said actually says that the other allocator will be the worse one. Indeed, glibc is known to hold onto memory longer and have more fragmentation than allocators like mimalloc and tcmalloc so I’m still at a lo…

> If there’s insufficient space it’ll get more virtual memory from the OS. Swap space is finite too. > Also, nothing you’ve said actually says that the other allocator will be the worse one. I'm not claiming that either is worse. I'm showing mathematically that for any two allocators that behave differently at all (with the one tiny exception of a pair of allocators that are perfect mirror images of each other), it's…

I should have been more explicit about the assumptions I make about an allocator:

1. If malloc() is called when there exists a contiguous block of free memory with size >= the argument to malloc(), the call will succeed. I think you'll agree that this is reasonable.

2. Bookkeeping (needed at least for tracking the free list, plus any indexes on top) uses the same amount of malloc()able memory in each allocator. I.e., if malloc(x) at some point in time reduces the number of bytes that are available to future malloc() calls by y >= x bytes under allocator 1, it must reduce the number of bytes available to future malloc() calls by y under allocator 2 if called at the same point in time as well. This may not hold exactly in practice, but it's a very good approximation -- it's possible to store the free list "for free" by using the first few bytes as next and prev pointers in a doubly linked list.

To head one another possible objection off at the pass: If the OS allocates lazily (i.e., it doesn't commit backing store at malloc() time, instead waiting till there is an actual access to the page, like Linux does), this doesn't change anything: Address space (even 64-bit address space) is still finite, and that is still being allocated eagerly. In practice, you could craft the differentially crashing program to crash much faster if you call memset() immediately on every freshly malloc()ed block to render this lazy commit ineffective -- then you would only need to exhaust the physical RAM + swap, rather than the complete 64-bit virtual address space.

Re: Make Ubuntu packages 90% faster by rebuilding them

#260
post #118

Earlier quoted context omitted.

Debug symbols do not need to be paged in so shouldn’t make much/any difference. Compiling with -O3 can increase code size a lot due to inlining, which can be a little bad.

Right, my humor there was that I'm assuming people specifically did non-debug flags for the build as an optimization. Only for them to still fall short. And understood a little on -O3 possibly increasing code size. I had thought that was more of a concern for tight environments than for most systems? Of course, I'd have assumed that -march=native would be more impactful, but the post indicates otherwise. I said in a…

> And understood a little on -O3 possibly increasing code size. I had thought that was more of a concern for tight environments than for most systems?

Increasing code size too much can result in hot functions not fitting in the icache, and that ultimately can make your program slower.

Post reply on HN