MSP performance tests

This mini-experiment was conducted to determine the computational overhead of various MSP routines common to my workflow. As any good computer scientist should know, optimization is useless without benchmarking!

Methodology

A poly~ patch was created for each test case. The DSP is configured with FS = 44100, IOVS = 1024, SVS = 512. A testing harness instantiates a poly~ containing the test patch and routes two signal inlets and two outlets. Noise is connected to the inlets and a scope to the outlets. The DAC is not connected to the outlets since we do not expect many of the patches to generate useful signals.

The number of voices in the poly~ object is then systematically increased until the user CPU load, as reported by MaxMSP in DSP Status reaches 45%. The total cost is reported in factors relative to the cost of a “nop” poly~ which is a pass-thru with no other object and at time of writing induces a 45% overhead at n = 1000.

Results

Test N at 45 Cost Factor Notes
pass 1000 1.0 Baseline, no operation
amp.to-db~ 110 9.1 Equivalent to atodb~
atodb~ 130 7.7
bound~ 750 1.3 minimum~, maximum~ cascade
complex.angle~ 85 11.8 atan2~
cycle~ 550 1.8 sample-rate frequency input
db.to-amp~ 37 27.0
dbtoa~ 37 27.0
delay.fractional~ 360 2.8 1.5 sample delay
fft-512~ 50 20.0 complex fft + inverse 512 points, no overlap
pfft-512~ 85 11.8 real fft + inverse 512 points, no overlap
onepole~ 510 2.0
plus~ 750 1.3
poltocar~ 65 15.4
pulsetrain~ 380 2.6 sample-rate frequency input
rms~ 130 7.7 rms mode of average~
slide~ 380 2.6 logarithmic slider
stat.standard~ 120 8.3 mean and std deviation
scale~ 600 1.7
index~ 450 2.2
db.to-amp.fast~ 240 4.2 downsampled 32:1 and smoothed
amp.to-db.fast~ 300 3.3 downsampled 32:1
rms.fast~ 280 3.6 downsampled 8:1

Conclusion

I am not surprised to see a high cost for operations such as atan2 and fft forward / backward transforms. The high cost of conversions from linear to logarithmic (amp.to-db~ and db.to-amp~) are remarkable, as is the high cost of performing an averaging filter (rms~) at sample rate. For these functions the .fast versions use a combination of poly~ and slide~ with the “down” argument to poly, enabling the object to run at a slower sampling rate, with a full-rate slide~ used to smooth its output. This strategy seems to work well for mitigating performance problems without requiring the use of the problematic max-message world (e.g. as would be the case if replacing average~ by average).