Skip to content

perf: Log is a port of Arm's optimized-routines log; fixes subnormals on amd64 - #17

Merged
tannevaled merged 1 commit into
mainfrom
perf/log
Oct 4, 2026
Merged

tannevaled merged 1 commit into
mainfrom
perf/log

Conversation

@tannevaled

Copy link
Copy Markdown
Contributor

Log went through Map(math.Log): 11.6 ns per element on a Zen 3 core
against NumPy's 4.2. It now runs a port of the double-precision log of
Arm's optimized-routines (the companion of the Exp port, glibc's since
2.28; MIT licence, attributed): a 128-entry {1/c, log(c)} table and a
degree-6 polynomial, a degree-12 one within 2^-4 of 1, and z/c - 1 as one
math.FMA, exact on every target. Log10 is log(x)*(1/ln10), math.Log10's
own formula, on this log.

Accuracy: worst 0.508 ULP against a 300-bit reference over 10 000 inputs
(math.Log: 0.727 on arm64). TestLogTable checks all 128 entries against
the properties log_data.c documents. Speed at 16 Ki on one core: M4
37 us (math.Log 72), Zen 3 73 us (math.Log 175, NumPy 69).

It also removes a Go bug go-ndarray inherited: Go 1.26's amd64 math.Log
is wrong for subnormal inputs (log(5e-324) = -709.09 instead of -744.44,
log(1e-310) = -709.09 instead of -713.80), confirmed on a real Zen 3.
TestLogSubnormal fails with the old Map(math.Log) under amd64.

🤖 Generated with Claude Code

… on amd64

Log went through Map(math.Log): 11.6 ns per element on a Zen 3 core
against NumPy's 4.2. It now runs a port of the double-precision log of
Arm's optimized-routines (the companion of the Exp port, glibc's since
2.28; MIT licence, attributed): a 128-entry {1/c, log(c)} table and a
degree-6 polynomial, a degree-12 one within 2^-4 of 1, and z/c - 1 as one
math.FMA, exact on every target. Log10 is log(x)*(1/ln10), math.Log10's
own formula, on this log.

Accuracy: worst 0.508 ULP against a 300-bit reference over 10 000 inputs
(math.Log: 0.727 on arm64). TestLogTable checks all 128 entries against
the properties log_data.c documents. Speed at 16 Ki on one core: M4
37 us (math.Log 72), Zen 3 73 us (math.Log 175, NumPy 69).

It also removes a Go bug go-ndarray inherited: Go 1.26's amd64 math.Log
is wrong for subnormal inputs (log(5e-324) = -709.09 instead of -744.44,
log(1e-310) = -709.09 instead of -713.80), confirmed on a real Zen 3.
TestLogSubnormal fails with the old Map(math.Log) under amd64.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tannevaled
tannevaled merged commit 21afa92 into main Oct 4, 2026
12 checks passed
@tannevaled
tannevaled deleted the perf/log branch October 4, 2026 14:36
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.

1 participant