Merry Christmas everyone,
Each time I use synfig I get a notification from my computer telling me high cpu usage from synfig.exec…It is the only program that makes my computer become slow and start chugging…I’m now worrying that the program might hurt my computer.
When I start working on an animation, I often end up giving it up as it is extremely slow and I sometimes have to wait for ages to see the result of an action.
Does anyone have the same problem or is it just me? If it’s a common problem, are you going to do something about it?
maybe you can try changing your quality preview settings from : Canvas Window Menu / View / Preview Quality
After the last few weeks of looking into the render and timeline code, I believe that could be part of the problem, due to a considerable amount of unnecessary recursion. My team is currently working on rewriting that using, among other improvements, a flyweight algorithm, for our fork. This is an important issue for us, as we need the animations to run on 256MB RAM, if not less. If it works out, I’ll let ya’ll know.
Yay! Good luck with that!
It would be awesome if you can make Synfig lighter and snappier!
A bit of an update on this. (Yes, I’m still here…update on that coming in the next few weeks, as I’m working a few things out.)
I contacted Quattlebaum with some questions regarding this, and the recursive structure is apparently necessary for how Synfig renders. Each layer must control its own rendering, and manage its own time. As a result, “…each layer is a bottleneck to hardware optimization.”
While we’re looking at some alternative approaches for our fork that optimize this for game engine animation, those approaches would wind up crippling most of Synfig’s advanced features. Thus, we’d need to look elsewhere for places to lower the CPU usage here in Synfig Studio.
That said, I know of two things that murder CPU in C++:
Dynamic Allocation: Anytime this can be avoided, the program will get a little bit faster. It is unavoidable overall, but there are undoubtedly places where it is not strictly necessary. Can anything be declared initially or statically? Can we implement object pools somewhere? (See this chapter from “Game Programming Patterns” by Robert Nystrom.)
Cache Misses: This is likely the best place to optimize, as this can make a program FIFTY TIMES SLOWER. It ties back into the dynamic allocation point. Right now, we’re throwing a whole lot of pointers around, but every time we follow the pointer, the computer has to load an entirely new chunk of memory in the cache, which wastes a bunch of CPU cycles. Instead, if we can store these non-dynamically, such as in a concurrent data structure, we would be able to speed things up considerably. See this chapter from “Game Programming Patterns” by Robert Nystrom.
In addition, we may be able to accelerate things by wrapping our own string class. Quattlebaum started the rough framework in synfig-core/src/synfig/string.h, but for whatever reason, it was never finished. Contrary to our instinct as C++ programmers, stl::string is actually a really inefficient class. Wrapping our own would save a considerable amount of memory and CPU usage, and assuming we include all the necessary functions in that class, we would only need to refactor stl::string to synfig::String to implement. By the way, wrapping one’s own string class is fairly standard for game engines and other memory-significant programs.
I hope that’ll be helpful towards this goal. I’ll be in touch regarding our exact involvement soon, but meanwhile, we’re still here and kicking.
Synfig rendering method (by layer in reverse order) suffers from the problem of what I call ‘perfection’. First, the great bottle neck is the render system itself. As every layer is mostly time dependent (everything is animatable) you need to be sure that you have the correct updated version of the layer before render it. That’s not avoidable in the final render (production) and using render farm system is not a problem itself. The problem is the live action for edition (and in your case for user response). IMHO, only by those paths it would save some render time:
- Sacrifice precision in favor of render speed. Integer instead of float when possible. Less blend methods available but faster. Simplified or limited raster effects.
- Cache what is not modified along the time. Don’t render twice what was rendered previously or it only needs one affine transformation (easy GPU programmable)
Of course those low level programming details will help and sure a lot. But the big change comes from a refurbish of the render system.
It was what I tried to do using Cairo. In its initial version it won the race with software but a render bug due to masking operations obligated me to rework the Cairo render usage (pass down the stack the context instead of the surface) and since then it is worse than Sofware even. Additionally, latest changes on the software render system to support single tile render and improve the mesh render for raster effects, put Cairo in one unusable situation.
So what I think is that to have success you need to refurbish a new render structure in parallel with the software renderer in order to not suffer its current “defects”
Good luck man!
No promises, as our fork has an entirely different purpose (game development, not strict cinematic animation), but once our rebuilt rendering system is done, ya’ll might be able to take that and adjust it. Just be aware - it flips the entire rendering logic over for performance, so it may require either a) heavy rewriting to make it usable for Synfig Studio, or b) rethinking of some major aspects of your current Layer system.
Not that anyone should shy away from trying to rewrite Render themselves. Usually the best solutions merge multiple ideas, anyhow.