Processing power spent to draw graphics in GUI vs buried in sub-patches
I've been operating under the assumption that graphic objects won't need to draw extra processing power if they're not actually being drawn, if for example, they are hidden deep in some sub-patch and not actually on the device's GUI. Is this true? I have a big table (1000s in width, dozens in height) that is constantly being updated, which would look pretty cool on the GUI, but I've kept hidden up til now. Would it be just as well to let it be seen, or no?
if it has not changed since max 4, GUI obejcts are processed also when they are hidden. simply because they cant know wether they are visible or not.
you can easily test that by opening a subpatcher or offsetting a bpatcher. is stuff drawn or emtpy? :)
general rule is, when you dont want to see them, dont use gui objects.
Thanks for the response. To make sure i understand how it all works, i have a follow-up question: Since M4L is always in overdrive, the actual drawing of the graphics (as with my table) are processed on the low-priority queue and only get taken care of when there's nothing more pertinent happening, and therefore will not actually slow anything else down anyway, while the data itself (which is being compiled and analyzed in important ways via the table) remains high-priority, correct?
there are people here who know it more accurate, but as far as i know, GUI objects (read: their drawing) kinda run in their own thread, i.e. they should not be more hungry when they receive messages in high priority.
you could, however, make it sure by putting a defer before each of them.
you can get away with alot in Max, so don’t hesitate to try the less efficient things if they’re easier for you, and just keep watching CPU… it’ll get easier to notice where to trim computations.
Yep, that's basically the way I've been going about it. I've successfully hacked together so many things that i couldn't even have dreamed up before i started working with Max. This here's just a refinement of what's already a pretty well-functioning machine.
From what you guys say, it looks like i should convert the table to a coll. Shouldn't be too difficult. I'll need to utilize a dump, in order to determine the highest value in the array, which is something I've already experimented with when trying to clean it up previously. (See https://cycling74.com/forums/how-many-loops-before-a-stack-overflow )
Peek~ + buffer~ is interesting; something i hadn't thought of. It did occur to me a little while ago that the way a professional would go about things would be to encode as much data as possible in actual signals, playing to the strengths of an audio language (sample-based accuracy and such). In this case I'm not sure i'd be able to find the highest point in the buffer~. Any ideas on how to? I will however most likely convert another part of my device to signal rather than coll-based data storage, probably with seq~. (See https://cycling74.com/forums/the-best-way-to-get-sub-millisecond-accurate-timing-please-advise/ )
As always, thanks for the help
I joined a thread last week about the same topic.
Looks like they are indeed processed even if hidden, but they spend an (even impressive) chunk of your CPU if they need to be redrawn every tot msec on your screen.
I think the best and easiest way to see the extra CPU your *visible* GUI objects are demanding is to minimize/hide the whole window-patch in you dock while it is running.
Then, of course, try put it back to front window, so that they are visible again.
CPU can go from 70% to 10% as you minimize it. And get back to 70% when you maximize it again.
When I use my Vj software in jitter and its running I send a hidden 1 message to all float and integer boxes (just to be sure) ;-)
Andro, how do you do that? Is it possible to use universal for it (somehow doesn't seem to work here)?
EDIT:
OK got it....
FWIW, GUI objects will not paint when not visible, so this cost should not be present. However, they will add themselves to check to draw which has a small cost and they will process any incoming data.
Cpuclock is telling me that the process takes longer on average with coll instead of itable. Why would this be? Even though it works (slowly) in my test patch, I can't get it to work once it's implemented in my actual device. It's like it's too slow to work under pressure or something? It actually does work in my device but only in edit mode and only using the MIDPLATEAU subpatch... I was surprised to see coll understood the inv message in the test, but when it fails in the device this seems like it might be where it's getting hung up... Very frustrating. Any ideas?
(I keep trying to post my test patch but apparently it just makes the site freeze)
(i've been having trouble posting copy-compressed patches too)
Test patch:
That did it Raja! Nice.
edit: so does anyone see the same slowness i'm getting with coll? In the test, version 1 takes ~.3ms with table and ~.9 with coll, while version 2 takes ~15ms with table and ~18ms with coll.
Actually I am setting points in the table in a fairly massive amount. Here's what's feeding into the table:
Every time a midi note is received roughly 20 numbers are sent into the SPREAD subpatcher, which turns each of those into roughly 61 (depending on settings) points to map. So now that you mention it, this is probably where the bottleneck lies. The whole issue is that I'm getting blips in my audio at each midi note. Currently I'm reorganizing my device so I can attempt to defer just this input and then pick up on high priority as soon as it's done. I'll let know how it pans out...
Still, would you say that coll should accept input faster than table? I wish i could get coll to work in the actual device. It seems like it should be a simple swap-out, but it's not turning out that way in practice.
Also, i tried table instead of itable a while ago and there was no difference.
Can't seem to get any sort of defer scenario to work. I think the best strategy might be to do like you say and use a buffer~, especially if there's a way to change the value of a range of it all at once, thereby eliminating the need for a SPREAD subpatcher multiplying the work 61 times. I'll have to delve further into the msp objects than i have thus far. Any place i should start looking (other than peek~ + buffer~)? I'll still need a way to determine the highest point in the buffer~ or it'd all be for naught...
Btw, my device is pretty complex but i doubt any of it is over your head. If you do want to see it in action and its entirety just email me at the address in my profile and i'll send you the .amxd, since you've been so helpful. I'm hesitant to post my unpatented secret million-dollar project up on the internet and just leave it there unguarded haha.
you’re resetting the ‘range’ and ‘size’ of the itable much too frequently(this is causing extra redrawing where unnecessary). use the ‘change’ object to catch and block repetitions…
Oh man! How did I not catch that! I added [change] and it took care of it. Or maybe i should say it mostly took care of it. I'm still getting a blip intermittently, but it only seems to be when the command to reset everything comes through the [r ---reset] (which is something I thought i took care of a long time ago by defering the 'clear' message to the table, but apparently not.) The only possibly expensive things happening at that time are the clearing of the table and maybe clearing the [histo 100000](?), which i tried deferring also, but no luck. I'll have to look further into it, but it's a huge improvement!
Multislider still may be the way to go, although i might still have to resort to a dump method of getting the address of (i should clarify that what i need is the address of and not just) the highest point, as i'm not seeing a replacement for the inv message in the documentation, and that would slow things considerably. BUT, the normalize message is very intriguing; it could be very useful for something else i have been looking to do in the patch for a long time...
No unfortunately right now i don't have a full version of max, but i should mention that these blips only give me troubles when i run the device normally and not when it's in edit mode, so that's how i've been averting the issue all along. It works but it's annoying.
So yeah, needless to say I'm glad you are still offering help in the m4l forum! i'll post back if i figure out anything regarding my remaining blip.
I haven't looked at this is much detail, but I thought I'd point out a couple of things if you are interested in trying it with [buffer~] and [poke~] or somesuch...
1. You can set a [buffer~] to hold numbers outside of -1/+1 by sending it the message "format float32". Then you're just storing 32-bit floats
2. have a look at [mxj buf.Op]. you can query sum, average, max, min, etc. you can also effectively change the range with the 'multiply' message.
Don't know if this is useful, just thought I'd let you know...
\M
Hello !
@SUN
i did not read everything on that topic but i get the idea of the problem ...
I have a question !
... is it crucial to represent "exact" data visually in your project ?
visual approximation of real content is not a deal here right ? im thinkin of dividing your data cells into fixed amount of rows and interpolating its output as a representation ... unless u want to draw on top of it.
#EDIT
im also wondering if it is not an overkill trying to represent thousands of rows in a lets say 200px width rectangle ,where u cant display those thousands of rows anyway. maybe its unnecessary effort trying to display exact content ?
Solved!
then again, maybe you don’t need to clear the itable at all(just clear histogram, since what comes out of histogram determines the range/size/data of itable anyways
At first i thought you might be right about this, but in my case only around 1220 (20 * 61) of the (usually) around 8000 indices get updated with each new note and the residual data in the table could easily mess things up. No matter, as it didn't alleviate the problem anyway.
Spending more time with it, i discovered the remaining blip wasn't actually happening at the time of the reset command, but with the first midi note after it. This was because the first note brought with it a flood of new maximum numbers to bound the table with, almost as if the [change]s had not been inserted. All i had to do was give the table a fixed width and it went away.
… is it crucial to represent "exact" data visually in your project ?
Visually? Not at all, but i do need it exact for the sake of analysis. The whole reason i'm using an itable (when it isn't even on the UI) is basically that it understands the 'inv' message. Up above i wasn't as careful with my words as i could have been, but what i need to find in this data is the index of the highest point (not the value of it). As my test patch up there demonstrates, sending the table a 'max' message to get the peak value and subsequently an 'inv' message to get the index of it is dozens of times faster than using a dump method of getting that info. With a dump method i was getting blips on every midi note. It would seem that the go-to non-UI object for this purpose would be coll, but it doesn't understand 'inv' and, according to my test patch, seems to be even slower on the dump. Although apparently it's faster at setting indices
1. You can set a [buffer~] to hold numbers outside of -1/+1 by sending it the message "format float32". Then you’re just storing 32-bit floats
2. have a look at [mxj buf.Op]. you can query sum, average, max, min, etc. you can also effectively change the range with the ‘multiply’ message.
Thanks for the info! I would like to compress the data (on both the x-axis and y), but since itable has only integer precision, that would mean corrupting it. 32-bit precision would be far more flexible! And it looks like [mxj buf.Op] can normalize and its max message finds the index as well as the value.. So i must say eventually buffer~ is where i wanna end up, but for now it's working and that's what counts! Thanks for throwing ideas back and forth; it's really helpful to troubleshoot this way.
Hi Sun !
Ok ,so u dont need to "see" anything .
You are about to find the peak value in certain period ?
all the rest of the history doesnt matter at all then ?
And what index represents actually ? is it just count of an event or it has specified role in all that "system" ?
This is long thread ,so maybe it was discussed already as what comes to my mind ...
is that
u dont need to fill so much data anywhere ,i would just look for last highest value on the fly .
i could imagine it like this ...
im sorry if this is out of the scope ,its just what came to my mind after your last "description" . maybe i should read all the posts , but seems to be late as perhaps you just solved your problem already . ok , have fun !!!