Added C# implementation of System.Math.ScaleB and System.MathF.ScaleB…#42476
Added C# implementation of System.Math.ScaleB and System.MathF.ScaleB…#4247616 commits merged intodotnet:masterfrom
Conversation
…, removed old bindings, added test cases.
|
Existing tests are based on xunit framework and located at From PowerShell, you can do: # build the whole thing just once
$ cd runtime
$ ./build.cmd -c Release
# then switch to the 'test' directory of library of interest, in this case
$ cd src/libraries/System.Runtime.Extensions/tests/
# build and run tests using restored toolset
$ ../../../../.dotnet/dotnet build /t:Test -c Release
# at this point, can modify code in src/libraries/System.Private.CoreLib/src/System and just repeat the command
# on line above to rebuild src+test (and their dependencies) for this library and then run tests. |
| public static extern double Pow(double x, double y); | ||
|
|
||
| [MethodImpl(MethodImplOptions.InternalCall)] | ||
| public static extern double ScaleB(double x, int n); |
There was a problem hiding this comment.
Could you please delete it from the unmanaged runtime:
src/coreclr/src/classlibnative/float/floatdouble.cpp
src/coreclr/src/classlibnative/float/floatsingle.cpp
src/coreclr/src/classlibnative/inc/floatdouble.h
src/coreclr/src/classlibnative/inc/floatsingle.h
src/coreclr/src/vm/ecalllist.h
Everything that references scalbn and scalbnf under src/coreclr/src/pal
There was a problem hiding this comment.
Also, I think these lines can be deleted from mono:
There was a problem hiding this comment.
@am11 icall-decl.h should be preserved, it's used by 6.x mono
There was a problem hiding this comment.
Ah, ok I see. We can then just delete two lines in icall-def-netcore.h and leave icall-decl.h and sysmath.c. Updated my comment above.
|
Tagging subscribers to this area: @tannergooding, @pgovind, @jeffhandley |
| { | ||
| class MathTests | ||
| { | ||
| public struct ScaleBTest |
There was a problem hiding this comment.
Why are we not using xunit tests in System.Runtime.Tests?
There was a problem hiding this comment.
Saw your comment above - take a look at https://github.com/dotnet/runtime/blob/master/src/libraries/System.Runtime.Extensions/tests/System/MathF.cs
There was a problem hiding this comment.
This is exactly what I was looking for before! I just missed it when I was looking for current tests. I'll just add my new test cases to the existing ScaleB tests.
Co-authored-by: Adeel Mujahid <adeelbm@outlook.com>
|
The mono changes look ok to me. |
|
For Mono, please wrap the corresponding icall implementations in runtime/src/mono/mono/metadata/sysmath.c Line 222 in 1905bde |
| #define log2 PAL_log2 | ||
| #define log10 PAL_log10 | ||
| #define pow PAL_pow | ||
| #define scalbn PAL_scalbn |
There was a problem hiding this comment.
Could you please also delete src\coreclr\src\pal\tests\palsuite\c_runtime\scalbn and src\coreclr\src\pal\tests\palsuite\c_runtime\scalbnf
|
What's next steps here? |
I'll get this reviewed either today or tomorrow. I'm not aware of anything else that would be blocking. It would likely be good to get perf numbers for x64, x86, ARM32, and ARM64. @DrewScoggins, is there currently an easy way to get these for a particular benchmark (aside from manually running them)? |
| throw new ArgumentException(SR.Format(SR.Argument_MinMaxValue, min, max)); | ||
| } | ||
|
|
||
| public static double ScaleB(double x, int n) |
There was a problem hiding this comment.
Was this ported from an existing implementation?
Based on #40956 (comment), it sounds like its based on the MUSL implementation which is MIT (https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT) and so we need a comment around here and also need to update the https://github.com/dotnet/runtime/blob/master/THIRD-PARTY-NOTICES.TXT.
CC. @richlander on if there is anything else required.
There was a problem hiding this comment.
The MUSL implementation came from Sun's implementation, so we may need the notice for that too (or just have notice for the Sun's implementation if it was not changed for MUSL).
There was a problem hiding this comment.
Yes, this was based on the musl implementation. I added links to the source for each function and included both the musl and Sun license. Let me know if I missed or can add anything.
| public static double ScaleB(double x, int n) | ||
| { | ||
| double y = x; | ||
| if (n > 1023) |
There was a problem hiding this comment.
Its probably not particularly important here, but the MSVC and the JIT tends to emit (assuming no PGO data):
if (condition) {
// predicted
}
else {
// unpredicted
}
This is inverse from what Clang/GCC do, so the n > 1023 and n < -1022 cases are going to be predicted as taken by default, while I believe they are edge cases in practice.
You can compare JIT (noting this is 3.1 output, not .NET 5, so there may be a couple minor differences): https://sharplab.io/#v2:EYLgxg9gTgpgtADwGwBYA0AXEBDAzgWwB8ABAJgEYBYAKGIGYACMhgYQYG8aHuGAHKAJYA3bBhgNIAO1wYGAEwgBXYABtxAZRYBBADIBRAEIB9FuQYBeBgA4AdAE4rVlEgCsSAOwo65ci6t6AajoABncAbgYAekiGYIRyXnJg0jouHn5hUXEpGXklVQ1tfWMWUgsGUhtSUhdQuis/WvdSYPIUPTgQqwjo2PjeOCTqtO4MkTEJCGlZBWU1Bk1dQxNGSztg0PI7OxqUT2Dt0h6YuISXVOoRpkZiciQ8uY0wbDUDAApZgoYENAYBSVkkgAlFdONQeBCHl8AJ7lBBhK4QgQAMwYb0kDAAfAwhnQQeDIYSwYTCbCAFSWRbFEzkBEEkk8DFwSy4ukMpGo9FYnHJPGIknE9mkhgUhZFZamNlCyFMlm8qXSngotEY7G4/GKiGCzUy8qs/lCgC+BshxvpppNMBUuHEyq5AB4GINkqQNQKTRDyZTxSUymSxUsSnQFeyMQE5dUnQxziGGXaMY7ndU3ULtZqvQHqaURZmJcGPSSwxGynBo/nzYr4wxE0NXQWifXQ+Uk0dGxCzYqOySzSbPvNFOUDAIMCwpkIYFAxFAbABJAGoIcYXAAFQgABF8mo3tuVFMAOZAt5xOjI1EBBjA6uOlyuoGxnjEdwMckMRQhs2GoA
To MSVC and Clang: https://godbolt.org/z/MEYGcz
There was a problem hiding this comment.
This is good to know. I tried reworking the logic to take this into consideration, roughly something like:
if (n <= 127 && n >= -126) {
// n is in expected range, just compute and return result
} else {
if (n > 127) {
// Make adjustments
}
else if (n < -126) {
// Make adjustments
}
}
But I'm not seeing an improvement in perf. I can push if you'd like to take a look, but not sure it's worth it.
There was a problem hiding this comment.
I can push if you'd like to take a look, but not sure it's worth it.
Right, I don't think in this particular case it is particular import, I just wanted to call it out as it might be relevant if additional work is done in this or related areas later.
There was a problem hiding this comment.
I was thinking that if those edge cases were moved into their own method, this could become inlineable. But it doesn't seem to get inlined even then.
| [InlineData( 2.71828183f, 2.71828183f, CrossPlatformMachineEpsilon * 10)] // value: (e) expected: (e) | ||
| [InlineData( 3.14159265f, 3.14159265f, CrossPlatformMachineEpsilon * 10)] // value: (pi) expected: (pi) | ||
| [InlineData( float.PositiveInfinity, float.PositiveInfinity, 0.0f)] | ||
| [InlineData(float.NegativeInfinity, float.PositiveInfinity, 0.0f)] |
There was a problem hiding this comment.
It looks like the diff for this file is bigger because the whitespace was stripped from the attributes.
It's probably a losing battle to try and fight with the formatter to keep the "columns" aligned, so I don't think it needs to be fixed; just wanted to call it out.
We already generate reports for the category subsets that are not Library and Runtime, but looking at the performance tests for this space, they are not in their own category. So what we can do is just generate a report that covers just the performance tests that we care about by name. We won't have this data for ARM32, as we don't have that hardware in the perf lab, but we should be able to generate the data for all of the other configs. Also this would be after the change already went in. |
Right, I know (roughly) how to do that bit. I was interested if we had any way to kick of a perf run against the current PR and to pull that info out before merging, short of just checking it out and running the tests locally on my own hardware. |
|
// Auto-generated message 69e114c which was merged 12/7 removed the intermediate src/coreclr/src/ folder. This PR needs to be updated as it touches files in that directory which causes conflicts. To update your commits you can use this bash script: https://gist.github.com/ViktorHofer/6d24f62abdcddb518b4966ead5ef3783. Feel free to use the comment section of the gist to improve the script for others. |
|
Is this currently blocked on anything and if so, can we help push it forward? |
|
@tannergooding My apologies, I think this slipped through the cracks on my end. I'll merge with master and push again. |
|
Thanks, and no worries! Just wanted to check in and see (and make sure I wasn't missing some action item on my end) 😄 |
| return x; | ||
| } | ||
|
|
||
| public static float ScaleB(float x, int n) |
There was a problem hiding this comment.
Just noting, since this PR was opened, AMD open sourced their own libm implementation which includes scaleb: https://github.com/amd/aocl-libm-ose/blob/7193ff6fdf72ecd68df4e0e19262da84f1d95a3e/src/ref/scalbnf.c
It notably has a different algorithm and error handling logic (unnecessary in the C# implementation) but it might be worth comparing in the future to see which is better.
tannergooding
left a comment
There was a problem hiding this comment.
LGTM. This should be good to merge assuming @jkotas doesn't have any other feedback about the JIT side changes.
|
Hello @tannergooding! Because this pull request has the p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (
|
|
Thanks again for the contribution @alexcovington! @adamsitnik, @kunalspathak, @DrewScoggins we should validate this shows up as an improvement in perf triage. |
|
Here is the improvement on Ubuntu DrewScoggins/performance-2#3838 Windows x64 DrewScoggins/performance-2#3857 Arm64 DrewScoggins/performance-2#3848 Windows x86 |
Implemented System.Math.ScaleB and System.MathF.ScaleB in managed C#, added test cases.
Submitting as a draft pull request first because I'm not quite sure where/how to integrate the tests I've written. System.Private.CoreLib does not have a test directory and I'm having trouble getting
build.cmdto find the tests. Any feedback would be appreciated!This is to address this issue regarding a performance difference in
System.Math.ScaleBandSystem.MathF.ScaleBon Windows and Linux. This PR improves the speed of the function on both platforms and removes the previous bindings/unmanaged implementations.Edit: updated description and added link to issue.