"In order to be absolutely sure to avoid unnecessary copy operations, you must perform copy operations."
I think there's a misunderstanding about. Let's assume a cross fader object with three signal inputs (sig2, sig2 and mix) and have a look at the following pseudo-code:
BAD:
mix = inlet3[i]
outlet[i] = inlet1[i] * (1 - mix)
outlet[i] = outlet[i] + inlet2[i] * mix
The first line might accidentally override the value of inlet2[i]
OK:
outlet[i] = inlet1[i] * (1 - inlet3[i]) + inlet2[i] * inlet3[i]
You can see that it's possible to read the inputs with making a copy.
GOOD:
mix = inlet3[i]
outlet[i] = inlet1[i] * (1 - mix) + inlet2[i] * mix
It's better to copy the value of inlet3[i] in a temporary variable than repeatedly accessing heap memory. The compiler would typically keep the value in a register. In fact, it would do the same with the "OK" example because it can see that the value of inlet3[i] doesn't change.
---
If you have several signal outlets, you might need to "copy" the input, but this is not necessarily a bad thing. Let's have a look at a pan object, again in pseudo code:
in = inlet1[i]
f = inlet2[i]
outlet1[i] = in * (1 - f)
outlet2[i] = in * f
We have to store the input values in temporary variables before writing to the outputs. Actually, this is better than accessing heap memory repeatedly and the compiler can keep the values "in" and "f" in registers.
---
Now here's an example where we need to "copy" the input without any obvious merit. Let's assume we want a multiline object:
in1 = inlet1[i]
in2 = inlet2[i]
vol = inlet3[i]
outlet1[i] = in1 * vol
outlet2[i] = in2 * vol
It turns out that this isn't really bad, either. x86 instructions can't take memory addresses both as source and destination operands, so the compiler has to load the input into registers anyway.
---
Finally, buffer aliasing is also about saving memory and reducing cache misses, probably more than avoiding copy operations.
Christof
On 23.05.2020 15:11, Roman Haefeli wrote:
On Sat, 2020-05-23 at 12:57 +0200, Christof Ressi wrote:
One word of warning about externals with multiple signal inputs/outputs (quoting from https://github.com/pure-data/externals-howto#signal-classes): "Optimisation of the DSP-tree tries to avoid unnecessary copy- operations. Therefore it is possible, that in- and out-signal are located at the same address in the memory. In this case, the programmer has to be careful not to write into the out-signal before having read the in-signal to avoid overwriting data that is not yet saved." This is still a bit vague, though, I would rephrase it like this: "In this case, the programmer has to be careful not to write into *any* out-signal before having read *all* in-signals"
Sounds to me like:
"In order to be absolutely sure to avoid unnecessary copy operations, you must perform copy operations."
I'm no C programmer, but I don't see how you can read *all* data before writing *without* copying it around.
Roman
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev