reducing number of send and receive objects to save CPU ?
hello,
I working on a project that usually use 64 or 128 instance of the same patch. they all contain parameters that should be controlled globally. what would be the best way to save cpu : having multiple send in each subpatchs , or having multiple inlets in each subpatchs, connected to the parameters ? Or would it be better to pack all the parameters, then unpack it in each sub patch in order to have only one inlet ?
I also experimented with poly~ and it works fine, although since i would like my patch to be m4live compatible , it seems like it's to be better to avoid poly~ for this reason. And even though poly~ is quite handy , in my project all the 64 instances of the patch are always activated and making sound/calculations, so i guess it's useless to use poly~ for that reason . thoughts ?
Given that Max is presumably compiled in a sensible language like C++, the parameters passed back and forth between the top-level patch and its sub-patches is going to done via the "stack" (last in - first out) or a block of dedicated "variable" RAM. As this memory is in constant use, I presume that the OS memory manager will keep this in the CPU cache for rapid access. If I have got that correct, then using multiple send objects or multiple sub-patcher inlets should be much the same in terms of CPU execution time. Packing the objects and then unpacking them again (which will involve invoking sub-routines in Max code) is just going to waste a lot of CPU cycles and slow things down.
I'd love to know from the development team if I have got that right!!!!
I’ve had a look at poly~ now and I’d suggest that the above applies equally well. The inputs and outputs for each instance will be mapped to blocks of RAM so that they are accessible by both the host patch and the poly objects. Without knowing exactly how they are compiled, it’s difficult to know what the CPU impact on each model would be. Poly~ is obviously aimed at sub patches that are disk based in origin and potentially dynamically variable in number. Managing that will have some CPU impact, so, if you have a fixed number of channels, embedding the sub-patches in your main patch might be more efficient.
Just my thoughts but I’d be happy for some expert input! 🧐
One other thing that I might recommend is a CPU/memory monitor called Process Lasso Pro from Bitsum.com. This is something I have come across recently after reading a blog about audio streams in DAWs getting broken up because of hungry, interrupt driven software hogging specific CPU cores that the DAW might also be trying to use to process an audio stream. I have to say that it produces a wealth of information regarding what is going on in the core of the OS in terms of thread and interrupt management and CPU core activity distribution. What it has revealed to me is that, whilst my patch project is large and complex and has a sizeable memory commitment with large numbers of handles to fixed memory locations (those send/receive and parameter passing locations), it is actually having minimal impact on CPU demands, especially compared with some OS kernel resources, drivers and other "low level" routines. It is also reassuring to see that my patch is not constantly being swapped in/out of the page file on the hard disk (page faults). Process Lasso can dynamically (or manually) reallocate time critical/high CPU demand programs, such as a DAW, to specific cores that are not being used by interrupt hogging routines and alter their threading priority so that audio processing is not maxed out and interrupted. It has had a dramatic effect on my DAW's capacity for audio processing and it would certainly help you get a direct measurement of CPU and memory demands with your different patch models.
hey sorry for taking so much time to respond! frankly i'm a bit overwhelmed by all the infos from your comments - it's really out of my field of knowledge and i understood half of it. however i will get back to it when i'll understand all those concepts more clearly. thank you!
even if all instances are always DSP-on, poly~ is a great way to send messages either to certain instances or to all at once.
packing messages into a list and unpacking them later, when the messages are successive and in the scheduler, will save nothing, it will require more CPU not less.
while it is mostly a matter of taste, so many s/r can easily get out of control, even if you type arguments into 64 subpatchers or use an auto-naming scheme. i personally would rather invest a few minutes into making hundreds of connections.