-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Add managed implementation of Math.ILogB and MathF.ILogB #56236
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…ion in ecallist and vm
|
I couldn't figure out the best area label to add to this PR. If you have write-permissions please help me learn by adding exactly one area label. |
|
Nice work! I suspect for Mono-interp in general it's better to have libc calls rather than long C# implementations, but I'm not sure how popular ILogB is in mono-interp related workloads. Do we have enough tests to cover all the edge cases? |
|
@EgorBo I see, I could put a guard around the implementation to just make the change for CoreCLR if you think that would be better. Do you know if there is a I looked at the current test cases, and it seems like there should be enough. I will double check the musl test cases as well to see if there are any others that could be added. |
| } | ||
| } | ||
|
|
||
| public static int ILogB(double x) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is some additional handling in src/coreclr/jit/valuenum.cpp that supports constant folding. We need to ensure that stays in sync with the managed implementation.
I'm unsure if there is a trivial way to get value numbering to defer to the managed implementation or if instead we need to maintain two copies of the code. @jkotas or @briansull may be able to help on this part.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be possible to defer to the managed implementation (for both JIT and AOT cases). It will require a new method on JIT/EE interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just as a summary...
With this change, we'll have 3 System.Math/MathF methods implemented in managed code:
RoundScaleBILogB
The first has a corresponding native implementation with CSE support, while the second only has a managed implementation and no CSE support.
One of the main concerns with moving all methods to managed is long term maintenance cost, especially around more complex methods like sin or cos. Hence we've done minimal investigation around having a single native implementation for all platforms taken from something like https://github.com/amd/aocl-libm-ose.
However, we do have some methods (like ILogB, ScaleB, and Round) that are "sufficiently simple" that implementing in managed code is probably worthwhile. It would be nice to ensure that we consistently handle them in CSE when we do move them to managed so we don't lose out on any existing optimizations and so we don't need to maintain 2 or more copies of the logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that for CSE logic specifically you do not need to do anything special w.r.t. to where and how the method is implemented - you can have it be an opague VNFunc and it'll work just fine (this is how a few cast helpers are implemented today).
The only place where the actual implementation matters is VN (or not VN) folding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Round, ScaleB, ILogB
Are typical implementations of these methods 100% precise, or are they approximations? I am thinking we really only need to solve this issue once we get to the managed implementations of methods that are implemented as approximation (sin, cos, etc.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Round is 100% precise.
I'm unsure of the guarantees of ScaleB or ILogB that we have, but I would expect these two in particular to be 100% precise as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The managed ScaleB and ILogB implementations are based off the musl implementations, which are 100% precise to my knowledge.
I was unaware that CSE might treat these functions differently, please let me know if there are any other changes I can make to help keep the implementations consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A more precise statement would be that we fold them in VN and thus need the native ilogb to always match the managed version. If both are precise (i. e. always return the same value for the same input), then we need not worry about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@SingleAccretion Thanks, that makes more sense. Since the musl implementations are 100% precise, I don't expect any mismatches.
Please let me know if there is anything else I can look at.
We do not optimize the runtime libraries for mono interpreter like this. We assume that performance critical methods will be AOT compiled in environments that do not allow JIT. |
| [MethodImpl(MethodImplOptions.InternalCall)] | ||
| public static extern double FusedMultiplyAdd(double x, double y, double z); | ||
|
|
||
| [MethodImpl(MethodImplOptions.InternalCall)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we clean these from sysmath.c, interp.c, mintops.def, icall-def-netcore.h and transform.c too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Absolutely, I've removed ILogB logic from those files. Please let me know if there is anything else I can modify.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
Tagging subscribers to this area: @dotnet/area-system-runtime Issue DetailsThis PR adds a managed implementation of Math.ILogB and MathF.ILogB based on the musl implementation. BenchmarkDotNet results: Please let me know if I can clarify anything. Thanks!
|
|
|
||
| public static int ILogB(double x) | ||
| { | ||
| // Implementation based on https://github.com/ifduyue/musl/blob/cfdfd5ea3ce14c6abf7fb22a531f3d99518b5a1b/src/math/ilogb.c |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we switch this to the official MUSL source: https://git.musl-libc.org/cgit/musl/tree/src/math/ilogb.c ?
At first glance, they appear to be identical and it would be better, IMO, to ensure we use the main source rather than a fork.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, makes sense. I've updated the citations, please let me know if there are any other changes I can make.
tannergooding
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This LGTM now that main is open for .NET 7 changes.
@dotnet/jit-contrib, @EgorBo could this get a review/sign-off from the JIT side.
Once this gets the JIT side sign-off, it can be merged.
@tannergooding There are no JIT changes in this PR. What do you want a JIT dev to look at? |
|
@BruceForstall, it was initially expected that there was going to be a ValueNum related change (https://github.com/dotnet/runtime/pull/56236/files#r675738468). It was determined that this was likely unnecessary since both the It would still be good for someone from the JIT to confirm there is no additional handling required/missed given the special casing that exists for the math intrinsics at various JIT stages. |
|
Ubuntu/x64 improvements in ILogB - dotnet/perf-autofiling-issues#1982 |
|
another one - dotnet/perf-autofiling-issues#1988 |

This PR adds a managed implementation of Math.ILogB and MathF.ILogB based on the musl implementation.
BenchmarkDotNet results:
Please let me know if I can clarify anything. Thanks!