VSTPlugin multithreading in scsynth

Splitting off to a new thread:

Just tried a little crude benchmarking. I used TDR Nova to test because it’s really CPU hungry in Linux (running via yabridge + wine) – about 10% per instance, well above the CPU usage signal’s noise floor. Introducing wine may affect some of the results, but I also tried loading empty instances of sfizz, which is Linux-native, to compare.

For a single VSTPlugin instance, I didn’t see any reduction in DSP CPU when multithreading was on, for either plugin.

For multiple instances, I saw about half CPU usage for 5 instances of TDR Nova (wine), and half CPU usage for 10 empty sfizzes.

So AFAICS VSTPlugin multithreading really kicks in when you’re running a lot of plugins – I’ll definitely consider that if I need a bunch of those TDR dynamic EQs (very nice free plugin!). I don’t think I have any plugins that multithread internally.

I’d also wondered if “block delay” meant control block or hardware block – confirmed that it’s control block (which is less than the delay introduced within TDR Nova).

Nice stuff – I hadn’t noticed that option. Related to the plugincollider thread, I stand corrected – you could parallelize multiple scsynths within scsynth this way, though with limitations and I’m not sure it’s really practical.

hjh

I think you have been misled by your own tests.

The purpose of the multithreading option is to offload plugin processing to helper threads. Typically, you would do that if the entire workload cannot (reliably) handled by the main audio thread.

For a single VSTPlugin instance, I didn’t see any reduction in DSP CPU when multithreading was on, for either plugin.

If there is no load on the main audio thread, it will just spin-wait until the task has been processed by one of the helper thread.

For multiple instances, I saw about half CPU usage for 5 instances of TDR Nova (wine)

Once you increase the number of plugins beyond the number of CPUs, the main audio thread will start to steal work from the helper thread, and that’s where you start to see actual performance improvements in your test scenario.

However, in real-world scenarios the main audio thread is typically busy with “normal” Synths, and that’s when you actually see the largest benefits. (If you only use VST plugins, you can get a similar effect by keeping some plugins on the main audio thread.)

Here’s a more realistic test:

  1. create some “normal” Synths until the Server is somewhat loaded.
  2. gradually add VSTPlugin instances with multiThreading: true → the Server CPU meter should stay roughly the same. (Beyond a certain number, the main audio thread may start to participate in work stealing or spin-wait and the CPU meter will rise accordingly.)

So AFAICS VSTPlugin multithreading really kicks in when you’re running a lot of plugins

I see how you came to this conclusion. However, that’s not really true. In fact, doing multithreading with many small plugins is less efficient than with fewer, but heavier plugins. The reason is that there is roughly constant serialization and context switching overhead per plugin. If the plugin takes little CPU time, this constant factor becomes more and more relevant.

In fact, the multithreading option works great with a single heavy plugin, as long as the main audio thread is somewhat busy. (If it weren’t, you wouldn’t need to use multithreading in the first place.)

Ah. Ok… I understand now.

The “no reduction in CPU” from single plugin instances was because the helper threads weren’t needed.

I was puzzled by that, but now it’s clear. Thanks.

hjh

Almost. In your test the plugin will be processed on a helper thread, but since the main audio thread has nothing to do, it basically has to spin until the helper thread has finished its task. That’s why you see CPU load on the Server, although it doesn’t really do anything useful. Once you add more work, that “phantom” CPU load goes away.