Skip to content

Commit 17591a0

Browse files
perf(math): record rejected fused-pow with inline exp2 minimax
Attacked the named fused-pow lever via the previously-UNTRIED approach: a fully fused single routine with an INLINE exp2 minimax (degree-12) + log2 hi/lo double-double, eliminating both libm::exp2 and libm::log2 calls. Prior rejections (bd-e4jb7k) had kept libm::exp2 as an external call; the open hypothesis was that inlining it would beat glibc. Result: 4-ULP-vs-glibc accuracy ACHIEVED (the 1M-point medium-pow sweep gate stayed green — new info), but 2.3-3.0x SLOWER than glibc for generic medium exponents (pow(x,2.1)=3.01x, pow(x,-2.3)=2.33x, pow(x,0.7)=2.38x). The inline degree-12 exp2 poly + the 64-entry log2 table + dd arithmetic is HEAVIER than glibc's hand-tuned fused asm, not lighter — eliminating the calls does not help. 4th rejection; the fused-pow lever is confirmed dead in safe Rust absent a verbatim transcription of glibc/ARM-optimized-routines pow.c tables (not in-tree, home-grown coeffs already insufficient, EV low at 1.9x on a cold profile). Reverted cleanly; pow stays on the libm::exp2(exponent*libm::log2(base)) path. Full analysis: tests/artifacts/perf/bd-fused-pow-arm-port-inline-exp2-rejected.md Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent c5209aa commit 17591a0

1 file changed

Lines changed: 37 additions & 0 deletions

File tree

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Fused-pow with INLINE exp2 minimax — REJECTED (perf), 2026-06-13
2+
3+
## What was tried (the previously-untried attack)
4+
Prior fused-pow rejections (bd-e4jb7k) all kept `libm::exp2` as an external call.
5+
The remaining hypothesis was: a *fully* fused single routine with an INLINE exp2
6+
minimax (no `libm::exp2`, no `libm::log2` calls) would eliminate the
7+
call/finalization overhead and beat glibc. This session implemented exactly that:
8+
9+
- `log2_kernel_hilo(x) -> (hi, lo)`: the existing `log2_kernel` with its already-
10+
internal `(hi, lo)` decomposition exposed (fast-two-sum renormalized), so the
11+
exponent multiply happens in double-double.
12+
- `exp2_dd_inline(wh, wl)`: inline `2^(wh+wl)` — integer split + a degree-12
13+
minimax (Taylor) polynomial for `2^r` on `[-0.5, 0.5]` (12 FMAs) + `scalbn`.
14+
- pow medium path: `(lh,ll)=log2_kernel_hilo(base); wh=y*lh; wl=fma(y,lh,-wh)+y*ll;
15+
exp2_dd_inline(wh,wl)` — no libm exp2/log2 calls.
16+
17+
## Result
18+
- ACCURACY: PASS. The 1M-point `pow_medium_log2_exp2_fast_path_large_sweep`
19+
4-ULP-vs-glibc gate stayed green. So 4-ULP accuracy IS achievable this way —
20+
this is new information (prior dd-lite attempts were perf-rejected, not measured
21+
for the inline-exp2 accuracy).
22+
- PERF: FAIL, 2.3-3.0x SLOWER than glibc for generic medium exponents:
23+
pow(x,2.1)=3.01x, pow(x,-2.3)=2.33x, pow(x,0.7)=2.38x (vs glibc, x in [0.5,2.5)).
24+
(pow(x,1.5)=0.58x is misleading — half-integer hits a different fast path.)
25+
The inline degree-12 exp2 minimax + the log2 64-entry-table kernel + the dd
26+
arithmetic is HEAVIER than glibc's hand-tuned fused-asm pow, not lighter.
27+
28+
## Conclusion (4th rejection — lever confirmed dead in safe Rust)
29+
Eliminating the libm calls does NOT help; the cost is the arithmetic itself. No
30+
safe-Rust composition (table-log2 + polynomial-exp2 + dd) beats glibc's tuned-asm
31+
pow — the gap is fundamental to glibc's autotuned register-blocked asm tables.
32+
The ONLY conceivable path is transcribing glibc/ARM-optimized-routines pow.c's
33+
EXACT 128-entry `__pow_log_data` + `exp_data` tables verbatim (not available in-
34+
tree; home-grown coeffs already proven insufficient). EV is low (1.9x on a cold
35+
profile) and risk/effort is high. Recommend leaving pow on the current
36+
`libm::exp2(exponent*libm::log2(base))` medium path. Reverted cleanly; no code
37+
shipped.

0 commit comments

Comments
 (0)