Experimental: Use fast_powf instead of powf for better performance in PID#11408
Experimental: Use fast_powf instead of powf for better performance in PID#11408DzikuVx wants to merge 5 commits into
Conversation
|
Interesting. I see it compiles to about 75 instructions vs roughly 380 instructions on ARM. |
There was a problem hiding this comment.
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()tosrc/main/common/maths.cand expose it viasrc/main/common/maths.h. - Replace
powf()withfast_powf()in fixed-wing airspeed TPA and I-term scaling computations insrc/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.
| // 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)); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Applied in commit 0b0404d. Changed (int32_t)result_exp to (int32_t)floorf(result_exp) so the fractional part is always in [0, 1), ensuring the 2^x polynomial approximation is always evaluated within its valid domain. Also added TestFastPowf unit tests covering base<1 edge cases (where result_exp is negative and fractional), base>1 general cases, special-case short-circuits, and invalid inputs.
|
Test firmware build ready — commit Download firmware for PR #11408 234 targets built. Find your board's
|
…of negative Use floorf to calculate integer part of exponent.
- Use floorf() instead of (int32_t) cast when decomposing result_exp into integer and fractional parts. The (int32_t) cast truncates toward zero, so for negative result_exp (base<1, common in airspeed TPA scaling) the fractional part would be negative, outside the [0,1] domain of the 2^x polynomial approximation. - Add TestFastPowf unit test covering special cases, base<1 cases (key regression), and base>1 cases with appropriate error tolerances. Agent-Logs-Url: https://github.com/iNavFlight/inav/sessions/ac361c30-4841-46d4-8d06-d704c02a2f7c Co-authored-by: sensei-hacker <1971284+sensei-hacker@users.noreply.github.com>
…s and unit tests Co-authored-by: sensei-hacker <1971284+sensei-hacker@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
No description provided.