Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

High CPU Usage on large parameter count (Bitwig/VST) #121

Closed
seegwen opened this issue Jul 6, 2018 · 8 comments
Closed

High CPU Usage on large parameter count (Bitwig/VST) #121

seegwen opened this issue Jul 6, 2018 · 8 comments

Comments

@seegwen
Copy link

seegwen commented Jul 6, 2018

  1. High CPU Usage on large parameter count (Bitwig/VST).

    As I increase the number of parameters in the txt file, the CPU usage of my daw (Bitwig) goes nuts. At 128 parameters, it is at 80%.

  2. Environment

    • OS: Mac OS El Capitan
    • DAW: Bitwig studio 2.3.4
    • Plugin: VST2 1.0.5
    • Audio Rate: 44100
  3. Is it expected behaviour ?

@pierreguillot
Copy link
Owner

Indeed, it's high. Can you send the files to create the plugin? What do you do with the parameters? Perhaps you use one parameter (or more) for something that is very CPU intensive.
From the documentation:

At each DSP tick, the plugin sends the current values of all parameters.

so

to avoid repeated and unnecessary calculations, most uses require filtering the redundant values with the object [change].

Also, instead of using parameters if you don't need the value to be automatable or if you want to save/recall complex values, you can use extra data of the programs.

Let me know if it helps.
Cheers

@pierreguillot
Copy link
Owner

I tried on a Mac 10.13 with Reaper 64: the CPU of a VST2 plugin with 128 parameters is around 2% (with the Debug binary, I guess the Release binary is more optimized).

So the cause could be the one I explained before - you do something very CPU intensive in your patch with the parameters - or Bitwig doesn't manage well large count of parameters - in this case, you should try with other plugins and perhaps contact them.

@seegwen
Copy link
Author

seegwen commented Jul 12, 2018

Hi Pierre,

Thx for your answer. Actually I really can't seem to find what I'm doing wrong computation-wise.
I'd like to send you the plugin, but I'd like to send it privately, maybe something will seem obvious to you. I'm sending it to your email address.

This patch receives CCs, and presents an GUI to control the DSI Evolver (HW synth) and works around a limitation of Bitwig by transforming the CCs and sending them to Pd patch by using netsend/netreceive. The Pd patch then transforms the received values to pure Sysex and out to the midi interface. It works really great, except for this high CPU usage that I don't understand the cause of.

I sent the patch to your (g) email adress.

Edit:
Actually, the problem might very well lie in my patch as you said since Ableton shows about same CPU usage.

@pierreguillot
Copy link
Owner

I will send you a suggestion for your patch on your email but as it can be interesting other people I try to reply in a generic way here. Perhaps that should even be in the documentation, in a section "How to manage with large number of parameters?".

Analyse the patch

First of all, one good practice is to use a module in Pd that fakes the parameters' changes at each DSP tick. This way, you can more easily see if the patch will be CPU intensive or not. You can use an abstraction as this param.fake.multi patch where the first argument defined the number of parameters:

param.fake.multi

The cause of the problem

So for each parameter you use an abstraction pretty similar to the param.get abstraction given with the examples:

param.get

This abstraction works for only one parameter but it receive all the parameters' messages and route the right value using the index given the first argument [route $1] (and then it sends the value to the [outlet] object or to a [send] object if a symbol is given for the second argument). So the "first part" of the abstraction ([receive param] -> [route $1]) will be triggered at each param message (that is receive at each DSP tick - every 64 samples). And if there are several abstractions, this will trigger the first part for all the abstraction at each DSP tick. And if there are a lot of these abstractions (corresponding to a large number of parameters), this can become pretty CPU intensive!

Solution of the problem

This is one solution that should reduce the use of the CPU when a large number of parameter is used. It surely can be even more improved and it's surely not adapted to all approaches and needs but in this particular case it reduced by half the use of the CPU.

The idea is to reduce the number of times that the [receive] objects and the [change] objects are triggered by reducing the management of the parameters to one abstraction param.get.multi:

param.get.multi

Let me know if it helps and if you suggestion to improve the abstraction.

@pierreguillot
Copy link
Owner

In fact, on my machine, it reduces the use of the CPU way more than the half! The patch that you sent me uses around ~13.2% of the CPU and now it's around ~2.2%!

@alfonso73
Copy link

@pierreguillot that's a brilliant solution! the only thing i don't understand is why you initialized the parameters array with a -999999999999...

@pierreguillot
Copy link
Owner

Because it's frequent that the default value is 0. The [change] object compares the new value with the one in the array and outputs the new value only if they are different. In this case, as the default value is 0 and the one in the array is also 0, the [change] object doesn't output the value at initialization (and that could be really difficult to debug).

@pierreguillot
Copy link
Owner

Fixed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants