Closed PJB3005 closed 4 years ago
Which methods?
Abs implementations all have fallbacks or are pass-thru I think.
[Pure, JbPure]
[NonVersionable, TargetedPatchingOptOut("")]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double Abs(double f)
=> System.Math.Abs(f);
[Pure, JbPure]
[NonVersionable, TargetedPatchingOptOut("")]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double Abs(double f)
=> System.Math.Abs(f);
[Pure, JbPure]
[NonVersionable, TargetedPatchingOptOut("")]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Abs(float f)
=> System.MathF.Abs(f);
[Pure, JbPure]
[NonVersionable, TargetedPatchingOptOut("")]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Abs(int a)
=> SlowMathIntegerAbs ? Ssse3.IsSupported ? AbsSsse3(a) : AbsNaive(a) : System.Math.Abs(a);
[Pure, JbPure]
[NonVersionable, TargetedPatchingOptOut("")]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static long Abs(long a)
=> SlowMathIntegerAbs ? AbsNaive(a) : System.Math.Abs(a);
None of the naive implementations use intrinsics.
Narrowed it down to bad impl of AbsNaive (int and long)
private static int AbsNaive(int a)
=> a * (Selector(a < 0) | 1);
^ Fix. Need to see what the performance impact is or if it'd be better to switch to a pass-through like the others.
using System;
using System.Runtime.CompilerServices;
public class Program
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int AbsNaive(int a)
=> a * (Selector(a < 0) | 1);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Selector(bool v)
=> Unsafe.As<bool, sbyte>(ref Unsafe.AsRef(v)) * -1;
// const compiles well
public static void X()
{
Console.WriteLine(AbsNaive(3));
Console.WriteLine(AbsNaive(-3));
}
// runtime *looks ok*
public static void X(int m)
{
Console.WriteLine(AbsNaive(m));
}
}
// const compiles well
Program.X()
L0000: sub rsp, 0x28
L0004: mov ecx, 3
L0009: call System.Console.WriteLine(Int32)
L000e: mov ecx, 3
L0013: call System.Console.WriteLine(Int32)
L0018: nop
L0019: add rsp, 0x28
L001d: ret
// runtime *looks ok*
Program.X(Int32)
L0000: sub rsp, 0x28
L0004: test ecx, ecx
L0006: setl al
L0009: movzx eax, al
L000c: neg eax
L000e: or eax, 1
L0011: imul ecx, eax
L0014: call System.Console.WriteLine(Int32)
L0019: nop
L001a: add rsp, 0x28
L001e: ret
CannyFastMath.Tests.PerformanceTests.AbsIntPerf(10000000)
System.Math.Abs processed 10000000 ints in 28ms
CannyFastMath.Math.Abs processed 10000000 ints in 4ms
Math functions like
Abs()
are completely broken when SSSE3 is not available (ARM is an example). This caused issues on both SS14 US West and raspberry.@Tyler-IN I don't even know if you care but you should probably be aware of this. Also if you don't have any intent of maintaining this repo I'm fine with archiving/transferring them.