Skip to content

Commit

Permalink
refactor(util): make RampingValue vectorizer-friendly
Browse files Browse the repository at this point in the history
Previously, invocations of `RampingValue::getNext()` caused inter-
dependence between loop iterations, making vectorization
impossible. This approach removes the state from `RampingValue`
and thus also the loop-iteration interdependence. `getNext()`
has been replaced by `getNth(int step)`.
While multiplication (`getNth`)is technically more expensive than
addition (`getNext`), the vectorization possibility results in a
1.1 - 6x speedup depending on optimizer-agressiveness.
  • Loading branch information
Swiftb0y committed May 26, 2022
1 parent 7a015cc commit 5b90361
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 15 deletions.
2 changes: 1 addition & 1 deletion lib/reverb/Reverb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ void MixxxPlateX2::processBuffer(const sample_t* in, sample_t* out, const uint f

// loop through the buffer, processing each sample
for (uint i = 0; i + 1 < frames; i += 2) {
sample_t mono_sample = send.getNext() * (in[i] + in[i + 1]) / 2;
sample_t mono_sample = send.getNth(i / 2) * (in[i] + in[i + 1]) / 2;
PlateStub::process(mono_sample, decay, &out[i], &out[i+1]);
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/effects/backends/builtin/echoeffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,12 +174,14 @@ void EchoEffect::processChannel(
pGroupState->prev_feedback,
engineParameters.framesPerBuffer());

int rampIndex = 0;
//TODO: rewrite to remove assumption of stereo buffer
for (SINT i = 0;
i < engineParameters.samplesPerBuffer();
i += engineParameters.channelCount()) {
CSAMPLE_GAIN send_ramped = send.getNext();
CSAMPLE_GAIN feedback_ramped = feedback.getNext();
CSAMPLE_GAIN send_ramped = send.getNth(rampIndex);
CSAMPLE_GAIN feedback_ramped = feedback.getNth(rampIndex);
++rampIndex;

CSAMPLE bufferedSampleLeft = pGroupState->delay_buf[read_position];
CSAMPLE bufferedSampleRight = pGroupState->delay_buf[read_position + 1];
Expand Down
10 changes: 6 additions & 4 deletions src/effects/backends/builtin/flangereffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,15 @@ void FlangerEffect::processChannel(
CSAMPLE* delayLeft = pState->delayLeft;
CSAMPLE* delayRight = pState->delayRight;

int rampIndex = 0;
for (SINT i = 0;
i < engineParameters.samplesPerBuffer();
i += engineParameters.channelCount()) {
CSAMPLE_GAIN mix_ramped = mixRamped.getNext();
CSAMPLE_GAIN regen_ramped = regenRamped.getNext();
double width_ramped = widthRamped.getNext();
double manual_ramped = manualRamped.getNext();
CSAMPLE_GAIN mix_ramped = mixRamped.getNth(rampIndex);
CSAMPLE_GAIN regen_ramped = regenRamped.getNth(rampIndex);
double width_ramped = widthRamped.getNth(rampIndex);
double manual_ramped = manualRamped.getNth(rampIndex);
++rampIndex;

pState->lfoFrames++;
if (pState->lfoFrames >= lfoPeriodFrames) {
Expand Down
2 changes: 1 addition & 1 deletion src/effects/backends/builtin/whitenoiseeffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ void WhiteNoiseEffect::processChannel(
std::uniform_real_distribution<> r_distributor(0.0, 1.0);

for (unsigned int i = 0; i < engineParameters.samplesPerBuffer(); i++) {
CSAMPLE_GAIN drywet_ramped = drywet_ramping_value.getNext();
CSAMPLE_GAIN drywet_ramped = drywet_ramping_value.getNth(i);

float noise = static_cast<float>(
r_distributor(gs.gen));
Expand Down
13 changes: 6 additions & 7 deletions src/util/rampingvalue.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@
template <typename T>
class RampingValue {
public:
RampingValue(const T& initial, const T& final, int steps) {
m_value = initial;
m_increment = (final - initial) / steps;
constexpr RampingValue(const T& initial, const T& final, int steps)
: m_start(initial),
m_increment((final - initial) / steps) {
}

T getNext() {
return m_value += m_increment;
[[nodiscard]] constexpr T getNth(int step) const {
return m_start + m_increment * step;
}

private:
T m_value;
T m_start;
T m_increment;
};

0 comments on commit 5b90361

Please sign in to comment.