q8fuel
(q8fuel)
January 19, 2022, 6:32pm
1
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
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();
q8fuel
(q8fuel)
January 19, 2022, 6:56pm
3
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 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.
q8fuel
(q8fuel)
January 19, 2022, 7:17pm
5
of course dude 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.
carbon14
(David O'Rourke)
January 19, 2022, 8:32pm
7
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.
q8fuel
(q8fuel)
January 20, 2022, 2:41pm
8
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);