3 ms·
I love arena allocation (which, incidentally, does entail dynamic resource destruction if you use it per-frame, and which is pretty easy to get wrong if you're
by Jweb_Guru 5y ago
I love arena allocation (which, incidentally, does entail dynamic resource destruction if you use it per-frame, and which is pretty easy to get wrong if you're just storing raw pointers everywhere--so good bye nice use after free properties), but you absolutely cannot just use arena allocation for everything. GPU resources in particular need to wait on fences and therefore can't have a neatly defined lifetime like what you're proposing unless you block your whole program waiting for these fences, while other GPU resources are (like I said) immutable and need to live for multiple frames. Where exactly do you store this data? How do you access it? How do you free it when it's done? How do you perform slow tasks like recomputing pipelines and shaders in the background without being able to dynamically track the lifetimes of the old/new backing GPU allocations? More generally, how do you track resources other than the framebuffer/surface, which are usually managed very dynamically and often appear and disappear between frames?
I think maybe it would be helpful if you would go look at the actual implementation of a nontrivial renderer and try to find one that doesn't allocate. Because the strategies you're describing don't match my experience working on renderers, at all.
- skohan 5y agoI am speaking from experience, I have written a lot of renderers. > GPU resources in particular need to wait on fences and therefore can't have a neatly defined lifetime like what you're proposing unless you block your whole program waiting for these fences, while other GPU resources are (like I said) immutable and need to live for multiple frames. I don't quite understand why fences are a problem here. As long as you know what frame a resource corresponds to, you just to have to guarantee that the entire frame is finished before reusing. You don't need to know what's happening at a granular detail within the frame. As far as static resources, that's easy: another arena for static resources which grows as needed and is shared between frames. Most of that data is living on the GPU anyway, so you just need to keep a list of the resource handles somewhere, and you're going to want a budget for it anyway, so there's no reason not to make it of finite size. > More generally, how do you track resources other than the framebuffer, which are usually managed very dynamically and often appear and disappear between frames? See the whole issue is trying to solve the issue "more generally". In many cases, you can know exactly the resources you will need (or at least the upper limit) when you start rendering a given scene. If you need to do any memory management at all, you can do it at neatly defined boundaries when you load/unload a scene. The only time when you need some kind of super dynamic renderer is when you are talking about an open world or something where you are streaming assets. Most of the serious renderers are written in C++ using custom allocators, which are just some kind of arena allocator under the hood anyway.
- Jweb_Guru 5y agoSorry, but if you think you can just get away with never deallocating any static GPU resources (as you're implying by "just use an arena"!), one of two things is going on: (1) You are manually managing an allocator on top of the GPU resources in the arena (reintroducing the usual use after free problems). (2) You have written a highly specialized renderer that cannot be reused across programs, as it requires all GPU resources used in any scene to fit into memory at once (and for their exact quantity to be known). Once you acknowledge that asking for dynamic GPU resource allocation, the rest of what I asked about follows; for instance, you can't reuse whatever portion of the already-allocated resources were freed at the end of the frame unless you can track used resources across frames; you can then either trace the open command buffers each frame or whatever (tracing all the live resources) or use something like reference counting and free once the fence is done (tracing all the dead resources). Hopefully you will acknowledge neither of these is the same as arena allocation. "dynamic GPU resource application isn't needed for a useful renderer" certainly sounds good, but again does not jive with my experience with renderers (admittedly, most of this involves rendering an open world with streaming assets, but most examples I've seen that aren't super tightly constrained examples require resource reuse of some sort).
- skohan 5y agoI think you are not thinking through all the possibilities here, but you would be surprised how far you can get with this approach
- Jweb_Guru 5y agoI would indeed be surprised. Like I said, point me to a production renderer used by more than one application that actually gets away with pure arena allocation except at blocking scene/frame boundaries. Until then, you're just asserting you can work within these restrictions without providing any examples. Considering that even stuff like hashmaps generally require allocations, it strikes me as fairly unlikely, but I could be convinced with code.