5

I have a revolutionary plan for avoiding hitching in my game engine due to frequent mallocs:

I'm just gonna preallocate a few gigs and disable purging, never giving the memory back to the system xD

Fuck you system! I will forever stay inside my process, you're syscalls can't screw my frame times now!

Comments
  • 5
    ram arena

    I know words!
  • 2
    I mean, that sounds pretty solid, can't you tell your runtime or allocator to hold onto a certain base amount of memory even if a significant portion could be freed?
  • 3
    that's quite a valid approach for frequently used memory

    PS: allocating memory during draws is a bad idea anyway
  • 3
    @12bitfloat what @jestdotty says. It's very common with graphic stuff in general. Nice wheel tho. Round enough? 😁
  • 1
    @retoor Yeah but thats too much work, Im lazy

    I'm just gonna use mimalloc as my arena, surely nothing will go wrong
  • 1
    @lorentz That's the plan!

    Use mimalloc and disable purging so it'll never tell the OS when pages aren't needed anymore. This way all the memory I need stays in the (hopefully very fast) mimalloc caches
  • 1
    Do I understand, based on this, that you're using the language of angels?
  • 2
    @retoor Sorry, should've written I'm Box::new()'ing all my memory ;P
  • 0
    @Demolishun Kinda... Normal types are easy but dynamically sized containers are of course always hard. There's an unstable allocator API for containers I guess I could use

    But my thinking is: mimalloc already is a kind of arena allocator (allocations are grouped into size classes) and it's thread-local and super fast, no locking at all

    So... as long as it doesn't interact with the OS a bunch it's essentially a really fast, generic arena allocator not much different from one I'd write myself

    And most importantly: I can be lazy and just use std containers :P
  • 0
    @12bitfloat even standard malloc is an arena allocator, but not always. there are two algorithms in use, one of which is basically a bunch of arenas
  • 0
    @iiii I know but the problem often is internal locking and it doing syscalls. I don't want it to start MADV_DONTNEED'ing 100 pages when I allocate during a frame
  • 1
    @12bitfloat fair nuff. using alternatives is a good idea in this case

    PS: also, don't allocate during frames. use object pools or something like that
  • 1
    @iiii Yeah I just read the mimalloc source and I don't think even with purging disabled I could use it for this purpose. Every 1000 and 10000 allocations it does bigger bookkeeping of collecting the heaps for unused blocks

    You're right, ultimately I should build a stack/linear allocator for temporary objects which I can just clear between frames
  • 0
    @12bitfloat what you've described is what people call "an arena". Just FYI what to search for on the web
  • 2
    @Demolishun The closest thing in Rust is MaybeUninit, at least that's what Box and other std types use internally.
  • 1
    @Demolishun I mean, Allocator returns a NonNull<[u8]> which is unceremoniously cast() into a NonNull<MaybeUninit<T>> and the rest after that pretty much follows high level Rust logic.
  • 0
    @iiii Bruh I know what an arena is. I'm just too lazy to implement one :D
  • 0
    @Demolishun placement-new is still debated in Rust. Right now it *can* happen due to optimizations but there's no formal rule like in cpp. There are some ideas around placement-by-return (if i remember correctly) but that's still in the idea stage
  • 0
    @Demolishun Really the issue is how do you make it compose? One level is fine I guess: `*target = Foo {..};` or `*target = init();` (where init straight returns a Foo) are fine. But if it get's more complicated than that how do you square the semantics of placement-new with your already existing semantics of object lifetime and new

    (I'm actually not sure, and I don't know the precise rules of cpp, but knowing cpp I would guess that they are pretty arbitrary in the first place lol)
Add Comment