FM with feedback/closed loops

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

2DaT wrote: Fri Dec 06, 2019 11:06 am
mystran wrote: Fri Dec 06, 2019 10:32 am
It should be noted that all modern compilers other than MSVC can normally cache heap variables in registers as well, unless there is some aliasing hazard.
There will be aliasing hazards with writes to pointers or dynamic structure of any kind such as vector.
C++ allows type-based aliasing and most compilers take advantage of this.

So if you have something like a struct containing your state variables, then this cannot possibly alias with a buffer of samples.

Post

SIMD makes a lot of sense if you don't do wavetables... a good approximation with one reciproce estimate operator instead of a division is surely faster than table lookups these days?

What I dislike about matrix based FM approaches is that you can't choose squared or exponential modifiers between modulator and carrier (or feedback). Also, feedback is typically run through a half sample delay 0.f * (y[z-1] + y[z-2]) to avoid ringing artefacts while non-feedback modulations are not afaik.

Post

mystran wrote: Fri Dec 06, 2019 11:26 am
So if you have something like a struct containing your state variables, then this cannot possibly alias with a buffer of samples.
If you write through float*, it will invalidate floats within the struct for sure. Compiler may do an aliasing check though, but it has to generate fail safe code if they do alias.

If you make 2 separate structures for state and buffer, it may work.

Post

2DaT wrote: Fri Dec 06, 2019 11:45 am
mystran wrote: Fri Dec 06, 2019 11:26 am
So if you have something like a struct containing your state variables, then this cannot possibly alias with a buffer of samples.
If you write through float*, it will invalidate floats within the struct for sure. Compiler may do an aliasing check though, but it has to generate fail safe code if they do alias.
Actually, if you index (or do something equivalent) through the float* then there is no need to invalidate any scalar floats anywhere, because clearly you are either doing invalid pointer arithmetics or the objects can't alias, because indexing implies an array of some sort, hence the types are unrelated.

Post

mystran wrote: Fri Dec 06, 2019 1:43 pm Actually, if you index (or do something equivalent) through the float* then there is no need to invalidate any scalar floats anywhere, because clearly you are either doing invalid pointer arithmetics or the objects can't alias, because indexing implies an array of some sort, hence the types are unrelated.
Zero index access can alias.

Post

2DaT wrote: Fri Dec 06, 2019 10:09 pm
mystran wrote: Fri Dec 06, 2019 1:43 pm Actually, if you index (or do something equivalent) through the float* then there is no need to invalidate any scalar floats anywhere, because clearly you are either doing invalid pointer arithmetics or the objects can't alias, because indexing implies an array of some sort, hence the types are unrelated.
Zero index access can alias.
Right, but if you peel the first iteration or check for the loop counter (which you might do for unrolling anyway), then the fast-path can still rely on the pointers not aliasing.

That said, the actual practice of compilers with respect to strict aliasing is often somewhat unpredictable and it doesn't exactly help that the relevant standards are vague to the point that there has been various proposals to clarify the rules.

Either way, this whole aliasing business is actually often suggested as the primary reason why Fortran (which forbids aliasing) can often produce faster numeric code compared to C (and C++).

edit: finally it should be noted that one can avoid this whole discussion by adding a "restrict" keyword in front of your buffer float*

Post Reply

Return to “DSP and Plugin Development”