Optimization / Cooking help

Hey folks,
Going through a project to try an optimization pass, but the process is new to me, and I want to make sure I understand whats going to be the right approach.

I’ve noticed that my CHOP networks seem to be always cooking even though there’s no activity coming from upstream. I put together an example tox to illustrate. There’s two branches which each have a null set to auto, and one set to selective… with a series of operations to visualize whats happening. Why do the automatic nulls continue to cook even though there’s no changes? Or to put it another way, what does automatic cooking actually mean?

In trying to wrap my head around this, I’ve noticed that by middle mouse clicking on any OP’s that simply by viewing the info, it causes a spike in cook times. I’ve also tried turning off the viewers, but this doesn’t seem to have an effect on the continuous cooking. How can one effectively optimize if requesting info about its state changes how it processes?

It seems a route could be going in and changing many of my nullCHOPS to selective, but perhaps while in perform mode TouchDesigner is already effectively doing this behind the scenes? Another bummer about this is that you dont get good end of chain visual feedback about if things are cooking unless you add another null as I have in this file…

I have a feeling I’m either missing something about how this works and how to approach this, or I’m massively overthinking something. Any pointers?
Thanks yall!

base_SelectiveCook.tox (1.6 KB)

Time sliced chops are unique in that they require themselves to cook every frame to produce results that are always correct across varying fps and circumstances.

There is a great write up here about it:

When a node is being viewed in the network, via the node viewer and nothing else, this forces the node to cook, if it should cook at all. so if a lag chop is up stream, and you are staring at a null a few nodes down in your network, you’ll see it cook:
cooksViewerActive
I know the gif compression makes it mard to see the wire animation, but it’s animating!

If you turn off the viewers for everything downstream of a timesliced node, and there are no other things requesting it (panel comps, renders, shaders, etc) then you’ll notice the noodle animation goes still .
cooksViewerInactive

So, if you are looking at a part of your network that seems to be cooking, if you know for sure that nothing will request it when in perform mode, then you can safely assume it will self optimize later when you’re not looking at it.

Performance monitor is a good way to check this while in perform mode, use the path to that component in your network, and click analyze. If you don’t see the node by name, it didn’t cook.

Also, when you middle mouse click on a node to get the performance info, it does take longer, not sure why - maybe just overhead for immediately requesting info from the chop. For that reason, this is not an entirely useful metric for anything other than comparative measures, if you want to know the actual cook time, use the performance monitor or drop an info CHOP down, and see it’s cook time that way.


All that said, if you have a need for things like lag chops, and lfo’s, and logic chops you’re going to have to make room in your performance expectations for their cooking every frame.

I have gone down the road of using tons of null chops as well with selective turned on, but I hazard against this as a fix all first solution, especially for complex / bigger networks because they have a nasty habit of getting delayed by a frame and causing any logic or visibility switching to get really glitchy or unusable. I’ve been unable to reproduce this in smaller more straight forward networks, so not sure entirely why it happens.

Also, null chops do incur a very small performance hit every frame that you will see if you check the performance monitor. This actually has added up for me in the past, when I had hundreds of selective nulls across many replicated sub networks.

There are ways to optimize performance though by changing how you use time sliced nodes. Here’s a few of my favorite work arounds / tricks regarding mostly chops - though it’s in no way comprehensive and the only ways. I’m sure others will chime in with some other great ideas and workflows:


  1. Switching between static and timesliced - If the result of a timesliced chop is only needed under certain circumstances, like when the mouse is inside a certain panel, or when a certain button or state is active, then a great solution is to switch between a constant(still) value and the timesliced value. Something like this:
    switchedLagChop
    Notice that even though the lfo noodle is animated , and we are viewing this in network, the stuff after the switch is still. I use this trick a lot, as it prevents the need for null chops. Of course, the function of your patch has to be conditional to benefit from this, in the case that it’s always on, this won’t really help.

  2. Move the timesliced parts as far down stream as possible - This one is easier to think of, but worth mentioning - move your timesliced data into a separate and parallel path, and do not merge it into your primary data flow until as far down stream as possible. Here’s a simple example of heavy processing happening above, and merged only at the end.
    mergeTimeSlicedDownStream2

  3. Keep timesliced stuff out of replicated containers if possible - This is something I used to do a lot, because it was convenient and usually more obvious how to achieve something when thinking inside a replicated module. However, replicated networks usually mean that is a dynamic part of your network, and any cook time you get in 1, gets multiplied across all of them obviously. Even if you prototype this way, always try and move it outside of the replicated area, when you can.
    Here’s an example of lags inside each comp, this would not scale very well:
    lagInsideReplicated
    Here’s an example of the lag outside, after the join, with lag per sample turned on:
    lagOutsideReplicated
    Lots of timesliced chops got the “XXX per sample” toggle added more recently-ish, and it is truly great. use this whenever you can!

I’ll leave it at that for now - hope that helps!

4 Likes

Yo thanks this is pretty great stuff. I think my issue is I have pretty uh, shall we say, liberal use of both lag and logic CHOPS. They’re so intuitive and straight forward and basic, I didn’t realize they were so performance heavy.

Culling through my network now to see if I can apply any of this.

1 Like

Hey,

really nice write up @lucasm!
The only other page I might point to is: Cook - Derivative for some further info on cooking in TouchDesigner in general.

cheers
Markus

2 Likes