Skip to content

Experimental: Use fast_powf instead of powf for better performance in PID#11408

Open
DzikuVx wants to merge 2 commits intomaintenance-10.xfrom
dzikuvx-pid-fast_pow
Open

Experimental: Use fast_powf instead of powf for better performance in PID#11408
DzikuVx wants to merge 2 commits intomaintenance-10.xfrom
dzikuvx-pid-fast_pow

Conversation

@DzikuVx
Copy link
Copy Markdown
Member

@DzikuVx DzikuVx commented Mar 7, 2026

No description provided.

@sensei-hacker
Copy link
Copy Markdown
Member

sensei-hacker commented Mar 7, 2026

Interesting.

I see it compiles to about 75 instructions vs roughly 380 instructions on ARM.

If we did this, we might want set set the apa_pow maxium to 199 rather than 200 to avoid a sudden unexpected change.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new fast_powf() approximation in the common math utilities and switches fixed-wing airspeed-based PID attenuation (TPA) calculations to use it instead of powf(), aiming to improve runtime performance in the PID loop.

Changes:

  • Add fast_powf() to src/main/common/maths.c and expose it via src/main/common/maths.h.
  • Replace powf() with fast_powf() in fixed-wing airspeed TPA and I-term scaling computations in src/main/flight/pid.c.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/main/flight/pid.c Uses fast_powf() for airspeed-based TPA and I-term scaling instead of powf().
src/main/common/maths.h Exposes the new fast_powf() API.
src/main/common/maths.c Implements fast_powf() using a bit-level log2/exp2 approximation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +137 to +155
// Using IEEE 754 floating point representation
union {
float f;
int32_t i;
} u;

u.f = base;
// Extract and compute: log2(x) ≈ (mantissa bits - 127) + normalized_mantissa
// IEEE 754: float = 2^(exponent-127) * (1 + mantissa/2^23)
// log2(x) ≈ (exponent - 127) + (mantissa / 2^23)

// Fast approximation: just use the exponent bits for log2
// More accurate version includes mantissa contribution
int32_t exp_bits = (u.i >> 23) & 0xFF;
int32_t mant_bits = u.i & 0x7FFFFF;

// log2(base) approximation with mantissa correction
float log2_base = (float)(exp_bits - 127) + (float)mant_bits / 8388608.0f;

Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The stated accuracy (~1–3% error) appears inconsistent with the current log2(base) approximation: using mantissa/2^23 as a linear proxy for log2(1+mantissa) can introduce much larger errors (e.g., base≈1.5, exp=2 gives >10% relative error). Please either tighten the approximation (e.g., add a better mantissa->log2 term) or update the accuracy/performance claims and limit the intended operating range accordingly.

Suggested change
// Using IEEE 754 floating point representation
union {
float f;
int32_t i;
} u;
u.f = base;
// Extract and compute: log2(x) ≈ (mantissa bits - 127) + normalized_mantissa
// IEEE 754: float = 2^(exponent-127) * (1 + mantissa/2^23)
// log2(x) ≈ (exponent - 127) + (mantissa / 2^23)
// Fast approximation: just use the exponent bits for log2
// More accurate version includes mantissa contribution
int32_t exp_bits = (u.i >> 23) & 0xFF;
int32_t mant_bits = u.i & 0x7FFFFF;
// log2(base) approximation with mantissa correction
float log2_base = (float)(exp_bits - 127) + (float)mant_bits / 8388608.0f;
// Use standard library log2f for accurate log2(base)
union {
float f;
int32_t i;
} u;
// Compute log2(base) accurately using libm
float log2_base = log2f(base);

Copilot uses AI. Check for mistakes.
Comment on lines +159 to +168
// Convert back to float: 2^result_exp
int32_t result_exp_int = (int32_t)result_exp;
float result_exp_frac = result_exp - (float)result_exp_int;

// Reconstruct float from exponent
u.i = (result_exp_int + 127) << 23;

// Apply fractional part correction using polynomial approximation
// 2^x ≈ 1 + x*(0.69315 + x*(0.24023 + x*0.05550)) for x in [0,1]
float frac_mult = 1.0f + result_exp_frac * (0.69314718f + result_exp_frac * (0.24022650f + result_exp_frac * 0.05550410f));
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

result_exp_frac can be negative when result_exp < 0 (which happens for base<1, common in airspeed scaling). The 2^x polynomial is documented as valid for x in [0,1], but the current int-cast decomposition allows frac outside that domain, which can increase error and introduce discontinuities around integer boundaries. Consider decomposing result_exp using floor (so 0<=frac<1) or otherwise ensuring the polynomial’s input range matches its documented validity.

Copilot uses AI. Check for mistakes.
Comment on lines +116 to +121
float fast_powf(float base, float exp)
{
// Handle common special cases for maximum speed
if (exp == 0.0f) {
return 1.0f;
}
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast_powf() is new math behavior in a file that already has unit tests (src/test/unit/maths_unittest.cc). Please add coverage that checks fast_powf against powf() across the expected domain (e.g., base in ~[0.015, 60] and exp in ~[0, 2]) with an explicit acceptable error bound, so future changes don’t silently degrade PID scaling.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Copy Markdown

Test firmware build ready — commit 6f36dfb

Download firmware for PR #11408

228 targets built. Find your board's .hex file by name on that page (e.g. MATEKF405SE.hex). Files are individually downloadable — no GitHub login required.

Development build for testing only. Use Full Chip Erase when flashing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants