Skip to content
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

Optimize Math.Round for arm64 and AwayFromZero for x64 #64016

Merged
merged 20 commits into from
Feb 13, 2022
Merged
28 changes: 28 additions & 0 deletions src/libraries/System.Private.CoreLib/src/System/Math.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1299,6 +1299,34 @@ public static double Round(double value, int digits)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double Round(double value, MidpointRounding mode)
EgorBo marked this conversation as resolved.
Show resolved Hide resolved
{
if (AdvSimd.Arm64.IsSupported)
{
// Inline the most common cases
if (mode == MidpointRounding.ToEven)
{
return Round(value);
}
EgorBo marked this conversation as resolved.
Show resolved Hide resolved
if (mode == MidpointRounding.AwayFromZero)
{
return AdvSimd.Arm64.RoundAwayFromZero(Vector128.CreateScalarUnsafe(value)).ToScalar();
}
}
EgorBo marked this conversation as resolved.
Show resolved Hide resolved
if (Sse41.IsSupported)
{
// Inline the most common cases
if (mode == MidpointRounding.ToEven)
{
return Round(value);
}
if (mode == MidpointRounding.AwayFromZero)
{
Vector128<double> valueVec = Vector128.CreateScalarUnsafe(value);
Vector128<double> tmp = Sse2.And(valueVec, Vector128.Create(0x8000000000000000UL).AsDouble());
tmp = Sse2.Or(tmp, Vector128.Create(0x3fdfffffffffffffUL).AsDouble());
tmp = Sse2.Add(tmp, valueVec);
return Sse41.RoundToZeroScalar(tmp).ToScalar();
EgorBo marked this conversation as resolved.
Show resolved Hide resolved
}
}
return Round(value, 0, mode);
}

Expand Down
29 changes: 29 additions & 0 deletions src/libraries/System.Private.CoreLib/src/System/MathF.cs
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,35 @@ public static float Round(float x, int digits)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Round(float x, MidpointRounding mode)
{
if (AdvSimd.IsSupported)
{
// Inline the most common cases
if (mode == MidpointRounding.ToEven)
{
return Round(x);
}
if (mode == MidpointRounding.AwayFromZero)
{
return AdvSimd.RoundAwayFromZero(Vector64.CreateScalarUnsafe(x)).ToScalar();
EgorBo marked this conversation as resolved.
Show resolved Hide resolved
}
}
if (Sse41.IsSupported)
{
// Inline the most common cases
if (mode == MidpointRounding.ToEven)
{
return Round(x);
}
if (mode == MidpointRounding.AwayFromZero)
{
Vector128<float> xVec = Vector128.CreateScalarUnsafe(x);
Vector128<float> tmp = Sse.And(xVec, Vector128.Create(0x8000000000000000UL).AsSingle());
tmp = Sse.Or(tmp, Vector128.Create(0x3fdfffffffffffffUL).AsSingle());
EgorBo marked this conversation as resolved.
Show resolved Hide resolved
tmp = Sse.Add(tmp, xVec);
return Sse41.RoundToZeroScalar(tmp).ToScalar();
}
}

return Round(x, 0, mode);
}

Expand Down