fix Math.pow_body for huge powers#53886
Conversation
|
Is my understanding correct that the theory behind this is that it moves the first iteration out of the loop? It's somewhat unclear to me why this makes a difference. |
Yes, I took the first execution out of the loop, because I wanted to half the size of |
|
Overall this looks good. I do want to do a little more testing with random giant comments to make sure this fully fixes the issues. |
This comment was marked as outdated.
This comment was marked as outdated.
|
The current state of the PR is an essential improvement in accuracy (only 150 ppm more than 1 ULP error) for big exponents, while performance is maintained. (The recent implementation has more than 34% in the same sampled argument area). |
|
The statistics are perfect now: 99.4 % of the samples now show 0 ULPS, 0.6% 1 ULPS error, no sample with more! Output with the version of this PR: The output of the same commands on v10.2 |
|
That looks great! It's also really nice to have a second person that actually understands this code well. Can you also post the benchmarks for |
|
In the realm of the old implementation, exponents are less than 2^25, the results are comparable both in accuracy and performance: The benchmark evaluates 10^6 powers and requires 59 or 51 ns mean value. New: For comparison the old implementation: Baseline for the benchmark: |
|
I also wonder whether it would be worth making it so that big powers go to the regular Float64^Float64 path. My bench-marking suggests that around |
Do you mean restrict the exponents to -20:20? Here we go: |
I will check, how performance verse accuracy works out. |
@oscardssmith yes, that would be a better way. I wasn't aware that we have a double precision implementation of log/exp behind the scenes. That has high accuracy for all integer exponents which can be represented as This is a separate PR, though. If that will be done, this PR is required not anymore. Nevertheless it was a challenging task for me to get out the last ULP of the algorithm, having much fun! Note, that there is still issue #53881. |
|
This PR is superseded with #53967 and closed. |
Improve performance of `^(::Float64, n::Integer)` in the case of `abs(n) > 2^13`. While `pow_body` is unreliable for `abs(n) > 2^25` this implementation provides errors of a few ULPs, while runtime is capped to that of the `Float64` implementation. Fixes #53881 See also #53886. (cherry picked from commit fe49d56)
Improve performance of `^(::Float64, n::Integer)` in the case of `abs(n) > 2^13`. While `pow_body` is unreliable for `abs(n) > 2^25` this implementation provides errors of a few ULPs, while runtime is capped to that of the `Float64` implementation. Fixes #53881 See also #53886. (cherry picked from commit fe49d56)
Improve performance of `^(::Float64, n::Integer)` in the case of `abs(n) > 2^13`. While `pow_body` is unreliable for `abs(n) > 2^25` this implementation provides errors of a few ULPs, while runtime is capped to that of the `Float64` implementation. Fixes #53881 See also #53886. (cherry picked from commit fe49d56)
Improve performance of `^(::Float64, n::Integer)` in the case of `abs(n) > 2^13`. While `pow_body` is unreliable for `abs(n) > 2^25` this implementation provides errors of a few ULPs, while runtime is capped to that of the `Float64` implementation. Fixes #53881 See also #53886. (cherry picked from commit fe49d56)
Improve performance of `^(::Float64, n::Integer)` in the case of `abs(n) > 2^13`. While `pow_body` is unreliable for `abs(n) > 2^25` this implementation provides errors of a few ULPs, while runtime is capped to that of the `Float64` implementation. Fixes #53881 See also #53886. (cherry picked from commit fe49d56)
Improve performance of `^(::Float64, n::Integer)` in the case of `abs(n) > 2^13`. While `pow_body` is unreliable for `abs(n) > 2^25` this implementation provides errors of a few ULPs, while runtime is capped to that of the `Float64` implementation. Fixes #53881 See also #53886. (cherry picked from commit fe49d56)
Improve performance of `^(::Float64, n::Integer)` in the case of `abs(n) > 2^13`. While `pow_body` is unreliable for `abs(n) > 2^25` this implementation provides errors of a few ULPs, while runtime is capped to that of the `Float64` implementation. Fixes #53881 See also #53886. (cherry picked from commit fe49d56)
Improve performance of `^(::Float64, n::Integer)` in the case of `abs(n) > 2^13`. While `pow_body` is unreliable for `abs(n) > 2^25` this implementation provides errors of a few ULPs, while runtime is capped to that of the `Float64` implementation. Fixes #53881 See also #53886. (cherry picked from commit fe49d56)
Improve performance of `^(::Float64, n::Integer)` in the case of `abs(n) > 2^13`. While `pow_body` is unreliable for `abs(n) > 2^25` this implementation provides errors of a few ULPs, while runtime is capped to that of the `Float64` implementation. Fixes #53881 See also #53886. Note: This was originally backported to 1.10 as ee8dd0f, but then reverted in 7f6ffc7 (cherry picked from commit fe49d56)
Fix
Math.pow_body(a, n)for huge values ofn.Fixes #53881