rack vs simd on monophonic synth

is there any benefits of using rack simd tools for monophonic synth?

ive controls for a 4xosc, but can’t param[].getValue using simd, neither inputs[].

its seems suitable only for poly/voices. correct? or can i benefit simd also for mono?

example: get freq 1/2/3/4 from param once, pitch 1/2/3/4 once and do freq4 * pitch4. the same for inputs…

this way also mono synth can benefit simd :slight_smile:

You can initialize float_4’s from single floats easily (the same value is copied for all the elements of the SIMD vector) :

        simd::float_4 parvalsimd = params[PAR_BAL_ATTN].getValue();

        simd::float_4 inportsimd = inputs[IN_BALANCE].getVoltage();

thats not what i need for improve processing by simd (param/inputs). on your example, on parvalsimd it should store PAR_BAL_ATTN + 0, PAR_BAL_ATTN + 1, PAR_BAL_ATTN + 2 and PAR_BAL_ATTN + 3 (i.e. all PAR_BAL_ATTN for each osc).

reading “once” from memory :slight_smile: the same as for getPolyVoltage() from inputs (the reason why it exist in fact).

simd::float_4 parvals_simd{params[PAR_1].getValue(),params[PAR_2].getValue(),params[PAR_3].getValue(),params[PAR_4].getValue()};

So, kind of annoying to write, but you could write some little function that does all that.

of course dude :slight_smile: but thats not taking advantage of simd/cache/pipeline and so.

as i said, the same reason why getPolyVoltage exist.

basically, with your code it does 4 memory read instead of a single one (roughly).

You just need to take that performance hit in this case for the initialization of the SIMD vector. That doesn’t affect how the subsequent SIMD operations work.

My SN-101 smooth noise oscillator is monophonic, but it uses simd for the noise algorithm, and actually for the random number generator as well.

of course. still not very “good” at performance, when you have lots of param/inputs to process. example:

simd::float_4 fillParam(ParamIds paramId) {
    return {params[paramId + 0].getValue(), params[paramId + 1].getValue(), params[paramId + 2].getValue(), params[paramId + 3].getValue()};
}
simd::float_4 fillInput(InputIds inputId, int voiceIndex) {
    return {inputs[inputId + 0].getVoltage(voiceIndex), inputs[inputId + 1].getVoltage(voiceIndex), inputs[inputId + 2].getVoltage(voiceIndex), inputs[inputId + 3].getVoltage(voiceIndex)};
}
simd::float_4 fillInputIsConnected(InputIds inputId) {
    return {(float)inputs[inputId + 0].isConnected(), (float)inputs[inputId + 1].isConnected(), (float)inputs[inputId + 2].isConnected(), (float)inputs[inputId + 3].isConnected()};
}

//

const rack::simd::float_4 paramPhase = fillParam(PHASE_PARAM);
const rack::simd::float_4 paramFreqOffset = fillParam(FREQ_OFFSET_PARAM);
const rack::simd::float_4 paramPitch = fillParam(PITCH_PARAM) / 1200.0f;
const rack::simd::float_4 paramNoiseMix = fillParam(NOISE_MIX_PARAM);
const rack::simd::float_4 paramNoiseTone = fillParam(NOISE_TONE_PARAM);
const rack::simd::float_4 paramVol = fillParam(VOL_PARAM);
const rack::simd::float_4 paramOut = (fillParam(OUT_PARAM) - 0.5f) * 2.0f;
const rack::simd::float_4 paramPan = fillParam(PAN_PARAM);
const rack::simd::float_4 inputVolIsConnected = fillInputIsConnected(VOL_INPUT);
const rack::simd::float_4 inputOutIsConnected = fillInputIsConnected(OUT_INPUT);