mathr / blog / #

Thoughts on [expr~]

overhead of [expr~]

(Graph labels are missing "~", couldn't figure out how to display "~" with GNUPlot...)

Pure-data's [expr~] is convenient for writing arithmetic expressions involving signal vectors, but unfortunately it has quite an overhead - it's much slower than patching objects together, [fexpr~] even more so.

This is because [expr~] interprets the parsed expression each DSP block, and because its inner loops don't have the unrolling tricks of Pd's signal arithmetic objects (search the source code for perf8 or perform8 or similar to see what I mean by that).

One way of solving it I thought could be for [expr~] to dsp_add() the corresponding inner loop perform functions at DSP chain recompilation time (ie, not very often). But that would require allocating signal vectors separately, as there is no way as far as I know to grab spare signal vectors from Pd's free pool (without having inlets or outlets to own them, that is). This would be a lot of work to get right.

An alternative (and the one I favour this moment) might be for [expr~] to create a new canvas behind the scenes and patch together the primitive objects making up the expressions. The more I think about it the more it solves problems: no need to duplicate the inner loops in multiple classes, no need to allocate (and deallocate) signal vectors, Pd can do its cache-locality beneficial signal vector recycling, the DSP chain compiler for patches does the topological sort so we don't have to, ...

Not sure how much it would benefit [fexpr~], but it wouldn't be too hard(?) to add support using [block~ 1] and [delwrite~]/[delread~] for the feedback signals. And I think [expr] could stay as it is, not so likely to be much of a hot code path.

A stepping stone to [expr~] dynamic patching might be to write an offline processor, that replaces instances of [expr~] in patch files by subpatches.

Does anyone feel up to the challenge? I'm not doing so much any more with Pd these days, so I'll pass.

You can download the C and Pd source code for running the benchmarks: thoughts_on_expr.tar.bz2