> Unsigned sizes are another historically common source of defects, and offer no practical advantages in return. Case in point exercise for the reader: Change each ptrdiff_t to size_t in alloc, find the defect that results, then fix it. I know that it’s a different “kind” of defect, but none of the code has overflow checks even with ptrdiff_t…
Arena allocator tips and tricks
71–80 of 99 posts
Re: Arena allocator tips and tricks
#72Earlier quoted context omitted.
Adding that when many linux distributions face OOM, a killer daemon steps in and might kill your service even if you were handling the situation properly.
Interestingly (confusingly), Linux's OOM killer is invoked for a different notion of OOM than a null return from malloc / bad_alloc exception. On a 64-bit machine, the latter will pretty much only ever happen if you set a vsize ulimit or you pass an absurd size into malloc. The OOM killer is the only response when you actually run out of memory. If you want to avoid your program triggering the OOM killer all on its o…
I guess in practice the kernel might be in such dire straits that it is not able to even swap to disk and might need to kill indiscriminately.
Re: Arena allocator tips and tricks
#73Earlier quoted context omitted.
Welp. Linus Torvalds was right about this stuff. https://lwn.net/Articles/316126/ https://lkml.org/lkml/2003/2/26/158
Wait until someone tells Linus about how processors do reordering. (Yes, I know he understands it. Clearly he just refuses to accept that compilers can also reorder his code and he needs to accommodate that.)
Re: Arena allocator tips and tricks
#74Earlier quoted context omitted.
> Having to decide ahead of time how much memory to allocate to the arena is... crap... A nice solution in many cases is to just keep a bunch of std::vector (or equivalent) around for the types you need, and .clear() them all at the start of each request/frame/message/whatever being processed. Calling push_back on a vector will only allocate when the vector's already reached its capacity, which will happen very rarel…
Generally, std::vector not going to work for allocator backend. The issue being, std::vector relocates all elements every time it increases the capacity. Therefore, adding an element to std::vector may invalidate addresses of all previously added vector elements. You gonna have to adjust your higher-level data structures which use that allocator, replacing pointers with offsets relative to the start of that std::vect…
Re: Arena allocator tips and tricks
#75Earlier quoted context omitted.
Generally, std::vector not going to work for allocator backend. The issue being, std::vector relocates all elements every time it increases the capacity. Therefore, adding an element to std::vector may invalidate addresses of all previously added vector elements. You gonna have to adjust your higher-level data structures which use that allocator, replacing pointers with offsets relative to the start of that std::vect…
std::deque, although it would be nice to use an implementation where you can control the block size.
The block size is controlled with a template argument, the number must be a compile-time constant.
Re: Arena allocator tips and tricks
#76Earlier quoted context omitted.
Interestingly (confusingly), Linux's OOM killer is invoked for a different notion of OOM than a null return from malloc / bad_alloc exception. On a 64-bit machine, the latter will pretty much only ever happen if you set a vsize ulimit or you pass an absurd size into malloc. The OOM killer is the only response when you actually run out of memory. If you want to avoid your program triggering the OOM killer all on its o…
I wonder if it is possible to avoid OOM by making sure that all allocations are done from a named (on disk, not shm) memory file. This way in principle is always possible to swap to disk and never overcommit. I guess in practice the kernel might be in such dire straits that it is not able to even swap to disk and might need to kill indiscriminately.
If you're going to do drastic things, you can configure Linux's memory overcommit behavior, although strictly avoiding overcommit usually results in trouble from software not written with that in mind.
Re: Arena allocator tips and tricks
#77The double-sided approach is useful for various purposes. For instance you can allocate short-lived data from the front and long-lived data from the back. It also makes better use of free space: with two separate arena allocators one could be out-of-memory but the other might have free space. With the double-sided approach all memory is fair game.
Re: Arena allocator tips and tricks
#78Earlier quoted context omitted.
Adding that when many linux distributions face OOM, a killer daemon steps in and might kill your service even if you were handling the situation properly.
The idea is that the server must have a known allocation budget, similar to Java's max heap size. There's a tree of allocators, i.e. a temporarily created arena allocator needs initial memory for its arena, so it can grab it from the root allocator. And the root allocator ultimately must be fixed-size and deterministic. Sure if there are other processes in the system allocating without concern for other apps, then th…
https://www.kernel.org/doc/Documentation/vm/overcommit-accou...
Re: Arena allocator tips and tricks
#79Earlier quoted context omitted.
As a share of the total number of programs written this is a minority indeed. How many pls are out there vs the number of libraries/apps? The number of deploys is a different thing.
Almost every program written in some programming language depends on the runtime provided by this programming language. Very few programming languages even let you to opt out of using the runtime. Which means that if the runtime needs something, then your program also needs it. Complexity doesn't magically go away when you put it into a library
Re: Arena allocator tips and tricks
#80Destructors are a very bad idea if you are using any form of garbage collection other than reference counting. The destructors won't run until some arbitrary time after the last access to the object, and in the case of arenas, what would be a very fast deallocation becomes proportional to the number of objects. Further, if destructors can revive objects, everything gets very complicated.