protonscr

[Suggestion] A thought on a custom sin/cos approximation

dxvkclosed
doitsujin/dxvk#4877 · opened 2025-04-26 by WapMap · updated 2025-04-29 · 3 comments · github
WWapMap 2025-04-26 github

I read the bug report and the associated PR regarding the implementation of a custom sin/cos approximation, and I wanted to share a thought that might be helpful. Considering the accuracy issue with the standard Intel implementation and your aim for a more precise approximation, perhaps it's worth considering using Chebyshev approximation instead of Taylor approximation. From what I know, Chebyshev polynomials, for the same order, provide better uniform accuracy compared to Taylor polynomials. This means that potentially you can achieve the same or even better accuracy using a lower-order Chebyshev polynomial, which in turn could lead to higher performance/efficiency/speed in computations. While implementing Chebyshev approximation might be slightly more complex than Taylor, especially in calculating the coefficients, there are standard methods and formulas for this.

WWinterSnowfall 2025-04-26 github

On a side note, Bhaskara I's aproximation would be, I think, quite a lot faster to compute, but I'm not entirely sure if it's more accurate than what Intel is doing in hardware. It would be hilarious if it were.

P.S.: @WapMap Could've commented directly on the PR, I think 😉 .

Ddoitsujin maintainer 2025-04-26 github

Precision is good enough as-is (it's only marginally worse than AMD's hardware instructions by various metrics), most (~2/3rds) of the shader instructions are about range reduction, mirroring and reconstructing the correct sign etc anyway, and that isn't really going to go away; the Taylor part is comparatively cheap to compute as we already only go to x⁷. Changing the algorithm would only really make sense if we could get comparable precision while significantly reducing the range reduction cost (e.g. if we could get this to (-π..π) instead of (0..π/4)) without losing any of the properties that our current code has.

I'd also need to spend several days of studying math again to re-learn how to do Chebyshev approximation because that was far from trivial and the internet really sucks at giving comprehensible answers to math questions.

What's arguably more important than minimizing or distributing the relative error in a specific way is that we maintain various properties of sin/cos, at least to a reasonable extent given the usual floating point math inaccuracies. This includes basic things like max(|sin x|) ≤ 1), sin² x + cos² x = 1, sin(x + π/2) = cos x, symmetries, sin(x+ε) > sin(x) for x in [-π..π) and sufficiently small ε, etc. The problem with Intel's implementation isn't just a relatively large error, it's also the fact that it deviates quite heavily from some of these expectations at times, and that's tripping up real-world algorithms, and this is part of the reason why the implementation looks the way it does.

FWIW, the maximum absolute error in an interval of [-2π..2π] of our approximation is in the ballpark of 1-e7, Intel's native implementation is more like 1e-5. Bhaskara is roughly 1e-3 so it's a complete non-starter for this purpose, I don't think you'd get anywhere with Newton-Raphson either without making it much more expensive than what we already have.

A completely different approach that I have considered is to use native sin and cos as a baseline, take the absolute minimum of the two, compute the absolute maximum of the two using sqrt(1-min(sin x, cos x)²), adjust signs accordingly and swap values depending on whether we used cos or sin. This would likely work on Intel because sin x is significantly more accurate than cos x for |x| < π/4, but has the disadvantage of still being very hardware-specific.

P.S.: @WapMap Could've commented directly on the PR, I think 😉 .

I don't really like having discussions on closed issues / PRs too much since those are very easy to miss.

WWapMap 2025-04-27 github

Understood, thanks @doitsujin for the detailed reply and @WinterSnowfall for the interesting suggestion with Bhaskara I's aproximation.

Nothing extracted yet.