perf(current-filter): make the averaging window a compile-time constant#10
Open
dakejahl wants to merge 1 commit into
Open
perf(current-filter): make the averaging window a compile-time constant#10dakejahl wants to merge 1 commit into
dakejahl wants to merge 1 commit into
Conversation
numReadings was a const-qualified variable, not a constant expression, so total / numReadings divided by a value loaded from memory on every 1 kHz current sample. Making the window a #define lets the compiler specialize the divide: on M3/M4+ it folds to a multiply/shift, and on M0 (no umull for the reciprocal multiply) it still calls __aeabi_uidiv but at least drops the runtime divisor load. While here, namespace the moving-average state (current_total, current_read_index, current_readings) and drop two globals that were only ever throwaway intermediates: smoothedcurrent (the return value) and smoothed_raw_current (now a local at its single call site). Window size and behavior are unchanged.
a94ed6d to
d87276b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Make the current-smoothing window a compile-time constant, and tidy up the moving-average state it touches.
Problem
The current smoothing averaged over
const uint8_t numReadings = 50;. Aconst-qualified variable is not a constant expression, sototal / numReadingsingetSmoothedCurrent()divided by a value loaded from memory on every 1 kHz sample — a__aeabi_uidivsoft-division call on Cortex-M0 (F051 et al.), a hardwareudivon M3/M4+. The surrounding state was also a handful of bare, generically-named globals (total,readIndex,readings,smoothedcurrent), andsmoothed_raw_currentwas a file-scope global used only as a throwaway intermediate at its single call site.Solution
Define
NUM_CURRENT_READINGS 50and use it for both the array size and the divisor. With a compile-time divisor the compiler specializes the divide: on M3/M4+ it folds to a multiply/shift, and on M0 — which lacks theumullneeded for the reciprocal multiply — it still calls__aeabi_uidivbut drops the runtime divisor load (verified with the bundled GCC 10.3.1 at-O3). The remaining changes are cleanup: namespace the moving-average state ascurrent_total/current_read_index/current_readings, and dropsmoothedcurrent(returned directly) andsmoothed_raw_current(now a local, with its singlegetSmoothedCurrent()call hoisted out of the#ifdef NXPbranches). Window size and behavior are unchanged; builds clean under-Werroron F051 (M0) and G431 (M4).Possible follow-ups, out of scope here — happy to discuss in review:
battery_voltagealready does) would eliminate the 100-bytecurrent_readings[]buffer and all the circular-buffer bookkeeping — a larger, behavior-changing simplification.