Live data from Hacker News

Always Bump Downwards (2019)

fitzgeraldnick.com

51–60 of 74 posts

Re: Always Bump Downwards (2019)

#52
post #44
post #42

Earlier quoted context omitted.

It matters because if the allocator cannot allocate a given amount, it should reliably return NULL to iform the caller that the allocation failed, not return a random invalid pointer that's not usable, which will lead to undefined behavior.

The API should restrict callers from providing bogus values at all.

How would the API do that without more overhead than the check that GP is suggesting?

Re: Always Bump Downwards (2019)

#53
post #43

Earlier quoted context omitted.

Agreed. The question really is if you should demand the user to enforce that constraint on the size they pass to you, or if the function itself should signal an error in that case.

I think it would be pretty reasonable to have an input type for that parameter that isn't a full usize and is instead some more restricted type that can only represent smaller values. The alignment parameter could be, like, u8, or maybe u16.

This still doesn't solve the overflow problem.

It's also too limiting: with u8 you can't ask for page-aligned data, and with u16 not for hugepage-aligned data. Granted, those aren't exactly prime use cases for a bump allocator, but it seems like poor design to limit the API unnecessarily.

Re: Always Bump Downwards (2019)

#54
post #45

Earlier quoted context omitted.

In most situations, the allocation size is a constant and bumping upwards can be done without an overflow check because the region cannot be close enough to the upper part of memory to wrap around. I'm surprised that there was no discussion of memory system performance. There are tons of OS-level and hardware prefetcher optimizations for forward-marching pointer references and zero-page allocation.

You can bump upwards without an overflow check even if the size is variable. I’ve seen multiple ways to do it. And I’ve lost days of my life to coming up with pointlessly amusing variants that get there in weird ways. Yeah I’m also amused that they didn’t get into the fact that downward bump is just not what the HW expects you to do. You’d need a real benchmark to see that effect. And, it’s an open question whether t…

Even when size is a full 64-bit value (…in that it might actually overflow the address space)?

Re: Always Bump Downwards (2019)

#55
post #34

Earlier quoted context omitted.

I think this doesn't work because `aligned + size` may wrap all the way around into the valid region again. For example if aligned == ptr + 1, and size is usize::MAX, we will end up with new_ptr == ptr and the allocation will wrongly succeed.

The straightforward answer is: don't tolerate ridiculous alignments.

You'd need to check for that, though.

Re: Always Bump Downwards (2019)

#56

I only recently learned about bump allocators. I was very confused as to how such an allocator could be useful. In reading the author's bumpalo crate [1] documentation, he cleared up my confusion. For one thing, this particular allocator is separate from the general allocator so the calling code can choose when to use the bump allocator. Quoting the crate doc: > [B]ump allocation [is] well-suited for phase-oriented a…

It is also used in WASM. I guess to increase memory safety

Bump allocators are very simple in an environment where everything you want must be brought with you.

Re: Always Bump Downwards (2019)

#57
post #8

Earlier quoted context omitted.

I think the lesson is "safety comes at a cost. If you bump downwards you can avoid those safety checks" I don't think the lesson is "let's just write unsafe code"

Caller asks for a 500 megabyte downward bump allocation in a 32 bit system. Do you check for underflow or not?

Most allocators will do this, yes.

Re: Always Bump Downwards (2019)

#58

I've heard that the Hotspot JVM uses a bump allocator but don't know the details. I'm sure it's heavily optimized though, so I'm curious about how this compares.

I believe HotSpot can move allocations out of the arena when garbage collection happens, which means fragmentation is less of an issue.

Re: Always Bump Downwards (2019)

#59

Earlier quoted context omitted.

You can bump upwards without an overflow check even if the size is variable. I’ve seen multiple ways to do it. And I’ve lost days of my life to coming up with pointlessly amusing variants that get there in weird ways. Yeah I’m also amused that they didn’t get into the fact that downward bump is just not what the HW expects you to do. You’d need a real benchmark to see that effect. And, it’s an open question whether t…

Even when size is a full 64-bit value (…in that it might actually overflow the address space)?

Phil style: track end and remaining. End doesn’t change. To allocate size, check if lesseq remaining and subtract from it. End minus remaining is the result (using the old value of remaining). Has two variants - one that burns an extra register but saves an instruction. Empirically, this one is fast enough that I just use it all the time.

Bmalloc style bump: independently subtract from remaining and add to bump. It’s more instructions but they are instruction level parallel.

Another friend’s bump style: have bump/end ptrs like usual. Fast path checks if size Note that instruction counts on these don’t matter so much on modern CPU’s. But dependency chain length does matter, a lot. Register usage matters only if you want to inline the allocator (and it’s not always beneficial to do it).

Re: Always Bump Downwards (2019)

#60

The rust code for rounding down is given as let new_ptr = new_ptr & !(align - 1); But I don't see rdx decremented before being negated and AND'ed with rax, in the assembly. What am I missing?

It's being converted into `-align` which is equivalent under twos compliment
Post reply on HN