Fast FIR Filtering

FIR Filtering Background

Inner Product

struct InnerProdFIR
{
int zPtr = 0; // state pointer
float z[FILTER_ORDER]; // filter state
float h[FILTER_ORDER]; // filter kernel
void process (float* buffer, int numSamples)
{
float y = 0.0f;
for (int n = 0; n < numSamples; ++n)
{
z[zPtr] = buffer[n]; // insert input into state
// compute two inner products between kernel and wrapped state buffer
y = std::inner_product (z + zPtr, z + FILTER_ORDER, h, 0.0f);
y = std::inner_product (z, z + zPtr, h + (FILTER_ORDER - zPtr), y);
zPtr = (zPtr == 0 ? FILTER_ORDER - 1 : zPtr - 1); // iterate state pointer in reversebuffer[n] = y;
}
}
};

Double-Buffered Inner Product

struct InnerProdNoWrapFIR
{
int zPtr = 0; // state pointer
float z[2 * FILTER_ORDER]; // filter state
float h[FILTER_ORDER]; // filter kernel
void process (float* buffer, int numSamples)
{
float y = 0.0f;
for (int n = 0; n < numSamples; ++n)
{
// insert input into double-buffered state
z[zPtr] = buffer[n];
z[zPtr + FILTER_ORDER] = buffer[n];
// compute inner product over kernel and double-buffer state
y = std::inner_product (z + zPtr, z + zPtr + FILTER_ORDER, h, 0.0f);
zPtr = (zPtr == 0 ? FILTER_ORDER - 1 : zPtr - 1); // iterate state pointer in reversebuffer[n] = y;
}
}
};

SIMD Optimization

// inner product using SIMD registers
inline float simdInnerProduct (float* in, float* kernel, int numSamples, float y = 0.0f)
{
constexpr size_t simdN = dsp::SIMDRegister<float>::SIMDNumElements;
// compute SIMD products
int idx = 0;
for (; idx <= numSamples - simdN; idx += simdN)
{
auto simdIn = loadUnaligned (in + idx);
auto simdKernel = dsp::SIMDRegister<float>::fromRawArray (kernel + idx);
y += (simdIn * simdKernel).sum();
}
// compute leftover samples
y = std::inner_product (in + idx, in + numSamples, kernel + idx, y);
return y;
}

Benchmarking Results

Finally

--

--

--

Jatin Chowdhury is a student.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Using the Jobs To Be Done Framework for Product Management

Understanding the AMAZON ELASTIC COMPUTE CLOUD

AWS Scaling (Reactive VS Proactive VS Predictive)

Create a riak_core application in Elixir (Part 5)

Campmates Mission

Engineering for tomorrow… while today happens!

picoCTF: Nice netcat…

PHPUK 2017 — A Recap

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Jatin Chowdhury

Jatin Chowdhury

Jatin Chowdhury is a student.

More from Medium

An Object Oriented Approach To Train an Image Classifier with Tensorflow

Debugging Neural Networks

[English] Udemy Review TensorFlow Developer Certificate in 2022: Zero to Mastery

Engineering Design by Genetic Algorithms and Finite Element Methods