Why you should always wrap Synth(...) and Synth:set in Server.default.bind { ... }

I can run 16000+ SinOsc synths on a single sc_server without any distortion. A ParGroup on supernova can’t even play 2000. Maybe I’m doing it wrong, but proper documentation is…lacking.

Dispatching a Node to a helper thread has a (rougly) constant cost. If your Synths are very lightweight, this cost can easily outweight the benefits of parallelization. Instead of putting all your tiny Synths directly in a ParGroup, you should rather distribute them into a few Groups and put those into the ParGroup. The Groups will be executed in parallel, but Synths inside each Group will run sequentially.

This is called “data partitioning” and it is an important concept for writing parallel programs. The basic idea is minimize the ratio between dispatching/synchronization cost and actual workload.

Unfortunately, the documentation of ParGroup is very sparse and does not really explain how to use it effectively…