Skip to content

Draft: Parallelised geometry update

PBS requested to merge pbs3141/inkscape:parallel-geometry-update into master

Continuing in the same vein as !4963 (merged), this MR parallelises the Drawing:update() function for a significant speedup on zoom/rotate of update-heavy documents.

A good example of the improvement is National_Grid_drawing.svgz, which goes from pretty chuggy to almost smooth (on a debug build).

Parallelism is achieved through OpenMP tasking, which internally uses a nice work-stealing scheduler to dynamically balance the workload between cores. (The only other widely-used library with a work-stealing scheduler is Intel TBB, which has an incompatible licence, and I don't want to have to write my own, so OpenMP it is, even if it's a Fortran hack. It's also already in use in Inkscape, so there's that.)

A heuristic based on the number of children (including clip/mask/pattern children) is used to selectively turn on parallelism only for heavy nodes. On the first run, when this information isn't available, a simpler heuristic based on the number of direct children is used instead, to avoid the first run being slow.

Certain modifications that occur during updating (namely, manipulating the cache and invalidating the canvas) are no longer safe to perform during update due to their modification of shared state, so these are stuffed into thread-local Util::FuncLogs instead and executed at the end when it is safe to do so (i.e. it's another deferral system, like in !4876 (merged)). Note that a mutex would not have been a good solution here, because invalidations can be generated at extremely high volume.

I've also thrown in an extension of the is/cast system from !4760 (merged) to DrawingItem, because I saw more dynamic_casts in update and render functions than I liked - sometimes more than one per node. There's also a mostly typo-fixing commit for the LPE test.

There's only one thing to look out for, and that is that different OpenMP implementations are used on different platforms. So while on Linux/Mac I think a work-stealing scheduler is used, I don't know whether the same holds on Windows (it probably does). And while on Linux I know that my mixing of OpenMP with C++11 concurrency works as expected, I don't know whether it will on other implementations. Fortunately there's a pretty decent test which will catastrophically fail if this latter requirement isn't met, which is as follows: Open two Inkscape windows each with a moderately complex SVG, and turn on "Animate" under rendering preferences. This causes both canvases to be very busy at the same time, which is otherwise hard to trigger. If the sky doesn't fall, it's good. Manipulating undo/redo at the same time would also strengthen the test. If I can get that confirmation on some non-Linux platforms, I'll be happy. (And if it's the opposite result, it'll be time for a lot of #ifdefs instead.)

Edited by PBS

Merge request reports