Cabbage Logo
Back to Cabbage Site

High CPU usage for the queue guiMode

Hi Rory,

While converting my instrument with many widgets (about 100) to the guiMode("queue"), I’m getting unexpectedly high CPU reading (MacBook Pro 15-inch, Mid 2015, MacOS 10.14.6, Cabbage 2.6.9).

To test this, I have a simple instrument with 72 rsliders (channel names “knob1”, “knob2”,…) set-up manually (not with cabbageCreate), which I am reading into a table:

knobs[] init 72
kind = 0
until kind==lenarray(knobs) do
    SID sprintfk "knob%d", kind+1
    ;knobs[kind] = chnget:k(SID)
    knobs[kind] = cabbageGetValue:k(SID)
kind += 1
od

While in my actual instrument the CPU is about double when using the queue mode, in this test I’m reading about 43% (queue mode) vs 24% (defualt). I’d expect quite an opposite behaviour?
Clocking the instrument (rtclock) gives me similar numbers of about 0.15 for the time difference (kt - kt0) / (ksmps/sr).

Am I missing something or is there really an unexpected performance hit?

Yeah, I noticed this myself recently. Thanks for the test code. You can still use chnget in queue mode. It should work fine. In the meantime I will look into this and see if I can spot the problem.

Thanks! The CPU load actually increases as soon as I change to the queue mode (with or without chnget). So maybe it is not due to the cabbageGetValue per se but something else in the background of the queue mode…

I think I’ve identified the problem here, although on my Windows PC I can run 1000 sliders in guiMode() without Reaper even registering it in its performance meter. I’ll try something later when I’m back on my Mac.

Hi @Samo Can you try the latest build, it should be ready in about 30 minutes. I tested with 300 sliders and the performance was the same in both modes. On the other hand, if I add an identChannel to each slider, guiMode("queue") wins hands down in terms of performance.

Great! But there are still some hiccups.

  • I made sure to get some “statistics” in my test and I’m reading about 1.2 times more CPU in the queue mode. Quite a different picture than before but still a tiny bit worse than default. The result seems independent if I add identChannel or not when only reading channels with cabbageGetValue (not setting them with cabbageSetValue).
  • Cabbage is now crashing consistently when I restart the script/instrument. But only in queue mode, not in default.

Old macs might be good … at least for some stress tests :wink:

Yeah, I just noticed that crash now myself. I was only testing in plugin mode :roll_eyes: Looking into it now…

[edit] I have a fix for that now, I’ll try to quickly get through the rest of this morning’s issues before I push to git :+1:

Super! I hope the queue mode will now also beat the default mode or at least be on pair with it.

It will take a little more tweaking. The real gain has always been in comparison to the identChannel() system. The new tweak I made yesterday also removed any potentially of blocking on the audio thread. This means that Cabbage can now run without modification on low latency systems such as the ELK OS and things like that. I’ll spend a little more time on it today and let you know.

[edit] btw @Samo, can you share how you are calculating your own performance info? I’d be interested in doing the same. Right now I’m working off the performance meter in Reaper. Your method might be a little more precise.

Sounds great!
I wish I could be more helpful with the metering, but I am just looking at the Activity Monitor for Cabbage task. Sorry! Maybe this is misleading? And the actual plugin will perform differently in a host?

I’m about to push through another fix. This one speeds up cabbageGetValue considerably. And also address some other issues. Here are my results with 300 sliders and the following code taken from your earlier post:

instr 1 
knobs[] init 300
kind = 0
until kind==lenarray(knobs) do
    SID sprintfk "knob%d", kind+1
    ;knobs[kind] = chnget:k(SID)
    ;knobs[kind] = cabbageGetValue:k(SID)
kind += 1
od
  • With default GUI mode, and both cabbageGetValue and chnget commented I get around 3.30% - with guiMode("queue") I get more or less the same.
  • With guiMode() set to default and chnget calls enabled I get 4.33%, and more or less the same in guiMode("queue")
  • With guiMode() set to default and cabbageGetValue calls enabled I get 4.15% :muscle: Again, it’s more or less the same with guiMode("queue")

I’m confirming with similar observations here (except my numbers are about +15 compared to yours - with only 72 sliders). Thank you for making the queue mode great again! :smiley:

1 Like

Now the hybrid mode doesn’t seem to function…?

The undocumented hybrid function it must be said. Is it really something you need? If so, I can add it back in…

[edit] It’s back in, just for you @samo!

I find it useful while translating from default to queue mode. So if the hybrid mode can stay without any bad side effects, I’m happy we have it, but if there are good reasons to remove it, I’ll adapt. Thanks!!!

I should put in a warning that all crypto-mining activities will be severely hampered by hybrid mode :rofl:

There seems to be another issue now :frowning: I believe it worked before, but now cabbageSetValue behaves strange. Could you please check this with a button widget:

kCount init 1
if metro(1) == 1 then
    kCount = (kCount+1) % 2
endif

if trigger(kCount,0.5,0) == 1 then
    cabbageSetValue "button1", k(1)
    ;chnset k(1), "button1"
endif

if trigger(kCount,0.5,1) == 1 then
    cabbageSetValue "button1", k(0)
    ;chnset k(0), "button1"
endif

It works with chnset, but not with cabbageSetValue. But cabbageSetValue works if it is outside the trigger block, making an impression that one k-cycle is not enough for it to execute. I’d like to have it in these trigger blocks because I’m triggering a bunch of other things within.

Also, it seems that now cabbageSetValue works in both default and queue modes?

cabbageSetValue "button1", k(1), kTrig1 ; trigger(kCount,0.5,0)
cabbageSetValue "button1", k(0), kTrig2 ; trigger(kCount,0.5,1)

also don’t seem to work…

Thanks, I’ll check this. The latest build did fixes the last issue you spoke off. I pushed yesterday evening.

Thanks! Which issue do you mean? I just tried the new version with no joy.

The one regarding the default modes. I was testing some things and accidentally pushed some code that enables queue mode to work while polling mode is enabled.