Prepare next frame with CPU during GPU render for animations
Rendering an animation has two distinct steps to each frame.
-
Update the scene to the new frame in the animation. (Load new textures/materials/objects if applicable, move meshes and such, add effects etc.) And rebuild the BVH.
-
Render it.
The first step is more or less CPU constrained.
While the second step is GPU constrained. The CPU has some work related to feeding the GPU new instructions during the render process, but it is a lot less compared to step 1.
Currently the total render time per frame is the total time of both steps.
But if we were to do step 1 of the next frame during step 2 of the current frame, then only the slowest of the two would be our render time per frame.
And for using both CPU and GPU rendering concurrently, if the CPU finishes step 1 of the next frame before the GPU has finished the current one, then the CPU can join in on rendering the current one. And when the frame is finished, the GPU can instantly start on the next instead of idling about for the CPU to finish its last bucket and set out on finishing step 1. (during this whole process, the GPU is already rendering the next frame instead of waiting.)
Downside of this parallel approach is that this will increase system memory requirements, since we need to store two versions of the output of step 1. (Current frame and next frame.)
Also preferably when processing step 1 we want to leave some spare CPU performance on the table such that we can maximize GPU throughput. Since otherwise the GPU will stutter and slow our progress down.
In the end. The render engine can be made to run a bit more parallel as far as GPU rendering is concerned and speed up animation renders, at the expense of more system memory utilization.
And of course have this as an optional setting in the: render settings -> Performance -> Final render. And place it beneath the "Persistent data" option. Since not everyone will want the downside of higher system memory usage.
4 Comments
IMO this is a useful proposal - if a bit too long, so i skimmed it - to reserve (double the amount of?) VRAM and pre-load the next frame. I do stuff like this with rendering 2-3 instances of the same scene on one gpu with light scenes... so this could be a smarter version of that.
I decided to trim away some of the needless fluff.
Rendering multiple images of the same prepared scene is interesting. I guess it is to have different exposure levels and/or camera settings?
That would be interesting, but not directly what I were talking about here. I consider it a bit wasteful to have the CPU almost idle while the GPU works, and vice versa. And CPU rendering is far too slow to meaningfully impact render times compared to this parallel approach. (at least for my projects.)
I meant rendering multiple frames of animation in parallel.
Ah, I interpreted the "light" as shading related and not as resource intensiveness ("weight") related.
Though, for a less intensive scene I have found preparing the scene for render to take a rather insignificant amount of time compared to larger scenes with more assets.
A crude example would be, doubling the amount of polygons in a scene has a rather marginal impact on rendering thanks to the BVH (ie step 2 doesn't really get slower. It is n+1), but packing the BVH structure for each frame takes about twice as long. Same for updating subdivisions and armature deformations etc. (ie step 1 gets slower. oversimplified: n+n)
The idea to running multiple instances of the same scene on the same system but render out different sections of the timeline as to keep the CPU more occupied, I somewhat feel that wouldn't scale to larger scenes in a practical fashion. Mainly since these instances wouldn't share static assets at all, bloating memory usage further on both GPU and CPU sides.