Skip to content

Multithreading (or rather multiprocessing) #80

Open
@XorUnison

Description

@XorUnison

A small disclaimer, this is more of a longterm issue with quite a bit of planning before any PR with actual merge intent should ever be attached to this.

First of all, what should we use?
There's the threading module, however it does not use additional cores. Using it isn't advised thusly, because it's theoretically possible max performance improvement is just +100% for all scenarios (you know, two threads per core usually), and actual performance increases are expected to be somewhere around +10% to +50%. Nothing irrelevant, but the simple fact is we can do better.

There's the multiprocessing module, and this is almost what we should use. There's also the multiprocess module that should generally be more robust (better pickling etc).
So multiprocess it is.

So, can it work? Yes it can. I've had to jump through some hoops but I managed to hack something together to multiprocess 4 simple scenes side by side. Theoretically possible speed bonus is +300% and actual was... +200%. Now that is nothing to scoff at. Obviously with more things processed simultaneously both theoretical and actual speed goes up, capped really only by the running hardware and available splitting. On my hardware with 16 cores I expect to be able to reach an actual improvement of about +1000% for example. That's around an order of magnitude so... it'd change things up a lot.

Alright, we've got the intent and the module, now onto the plan.

First we should enable multiprocessing for scenes. Multithreading is really easy, but multiprocess is a bit more picky. As I said, I have gotten scenes rendered in it but something about the exact implementation in extract_scenes.py is still making it fail while pickling. I'm not sure what it is, I just know that it can be fixed, since I was able to sidestep it.
(Fixed, see next post for that)

Once that is done we should be able to use manim (assuming 4 scenes in a file) with something like this:
manim project -at
And have all 4 scenes dropped into their own process.

Once this is implemented and works well, we can move on to the real prize.
In order to make manim faster in general we can split scenes into intervals, and then have each interval be handled by a separate process. For instance if a scene has 8 animations then we could split them like [1,2], [3,4], [5,6], [7,8] and throw each interval into its own process.
Now this would mean that some calculations are done multiple times. While the process rendering [1,2] would have no overhead, the one rendering [3,4] would have to do the calculations of [1,2] before it can start rendering. However those calculations are usually very, very short compared to the rendering process, so that's not really much of an issue.

Last but not least, we'll want this multiprocessing to be an option, not replacing the current way of serial rendering. Aside from making sure we have options if something ever causes issues, some people use manim to render stuff that is actually very heavy in calculations, like fractals. For those cases multiprocessing could actually be actively detrimental, and aside from just needlessly hogging computing power could also overflow the RAM. So multiprocessing shouldn't be on by default, but when it's in we should make sure everyone knows it's there. Maybe even drop a small message every time manim runs with just 1 process.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementAdditions and improvements in general

    Type

    No type

    Projects

    Status

    🆕 New

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions