ImageEngine/gaffer — pull request #893 by johnhaddon (2014-07-01 14:57:48+00:00)
Title: Instancer optimisation

While playing around with the Instancer in a profiler, I was noticing substantial chunks of time where only one processor was doing anything. This makes sense when you consider that currently in Gaffer we rely on threading in the renderer to be evaluating different parts of our scene in different threads. When a procedural expansion hits the root of an Instancer, there's a substantial amount of computation performed to compute both the names of the children, and also the correct bounding box taking into account all the different bounds and transforms the instances have (as they can each be unique, driven by the instance id in the context). This was all being performed in one call to hash()/compute() leading to the other cores stalling while a single core figured that stuff out.

This pull request implements substantial optimisations to this bound computation process at the root of the instancer, both parallelising it and optimising the basic operations. It yields an 18x speedup in the root bound computation on a 6 core workstation, and a 7x speedup on my 2 core laptop. Winner!

There are a few other places in Gaffer where we might like to consider using finer-grained parallelism like this - `SceneNode::unionOfTransformedChildBounds()` and `SceneNode::hashOfTransformedChildBounds()` being one very obvious one. We might also like to implement deformers and our OSLObject node to perform in parallel over batches of vertices, for cases where there is a single large object, and we can't gain performance simply by processing many objects in parallel.