From b643eade0d732430dfae36ef478eb360ffb0c675 Mon Sep 17 00:00:00 2001 From: Ahmet Inan Date: Tue, 6 Oct 2020 20:10:11 +0200 Subject: [PATCH] added sliding window accelerator --- README.md | 6 +++++- sma.hh | 19 +++++-------------- swa.hh | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 15 deletions(-) create mode 100644 swa.hh diff --git a/README.md b/README.md index 73c935e..0eb77c0 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,11 @@ The [simple moving average](https://en.wikipedia.org/wiki/Moving_average#Simple_ * SMA1 computes the sum of its internal history buffer at each new input from scratch is and therefore very slow. * SMA2 updates its internal sum using only the new input and the oldest value in the history buffer. It is therefore the fastest of all and works perfect with integers but suffers from drift when used with floats on sequences having a high dynamic range. * SMA3 is based on SMA2 but uses the [Kahan summation algorithm](https://en.wikipedia.org/wiki/Kahan_summation_algorithm) to reduce drift significantly. -* SMA4 uses a tree and only update nodes that depend on the new input value and is slower than SMA3 but it has no drift. +* SMA4 uses a tree and only updates nodes that depend on the new input value and is slower than SMA3 but it has no drift. + +### [swa.hh](swa.hh) + +The sliding window accelerator uses a tree and only updates nodes that depend on the new input value for the pairwise reduction. ### [bip_buffer.hh](bip_buffer.hh) diff --git a/sma.hh b/sma.hh index 8cb0c11..6502aa4 100644 --- a/sma.hh +++ b/sma.hh @@ -7,6 +7,7 @@ Copyright 2019 Ahmet Inan #pragma once #include "kahan.hh" +#include "swa.hh" namespace DSP { @@ -92,24 +93,14 @@ public: template class SMA4 { - TYPE tree[2 * NUM]; - int leaf; + struct Add { TYPE operator () (TYPE a, TYPE b) { return a + b; } }; + SWA swa; public: - SMA4() : leaf(NUM) - { - for (int i = 0; i < 2 * NUM; ++i) - tree[i] = 0; - } TYPE operator () (TYPE input) { - tree[leaf] = input; - for (int child = leaf, parent = leaf / 2; parent; child = parent, parent /= 2) - tree[parent] = tree[child] + tree[child^1]; - if (++leaf >= 2 * NUM) - leaf = NUM; if (NORM) - return tree[1] / VALUE(NUM); - return tree[1]; + return swa(input) / VALUE(NUM); + return swa(input); } }; diff --git a/swa.hh b/swa.hh new file mode 100644 index 0000000..c92e649 --- /dev/null +++ b/swa.hh @@ -0,0 +1,35 @@ +/* +Sliding window accelerator + +Copyright 2020 Ahmet Inan +*/ + +#pragma once + +namespace DSP { + +template +class SWA +{ + TYPE tree[2 * NUM]; + int leaf; + OP op; +public: + SWA() : leaf(NUM) + { + for (int i = 0; i < 2 * NUM; ++i) + tree[i] = 0; + } + TYPE operator () (TYPE input) + { + tree[leaf] = input; + for (int child = leaf, parent = leaf / 2; parent; child = parent, parent /= 2) + tree[parent] = op(tree[child], tree[child^1]); + if (++leaf >= 2 * NUM) + leaf = NUM; + return tree[1]; + } +}; + +} +