Hahah color lerp.
This commit is contained in:
@@ -1,15 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
#if NETCOREAPP
|
||||
using System.Runtime.Intrinsics;
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
#endif
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Robust.Shared.Maths;
|
||||
using SysVector4 = System.Numerics.Vector4;
|
||||
|
||||
namespace Content.Benchmarks
|
||||
{
|
||||
[DisassemblyDiagnoser]
|
||||
public class ColorInterpolateBenchmark
|
||||
{
|
||||
private readonly List<(Color, Color)> _colors = new List<(Color, Color)>();
|
||||
private (Color, Color)[] _colors;
|
||||
private Color[] _output;
|
||||
|
||||
[Params(100)] public int N { get; set; }
|
||||
|
||||
@@ -18,6 +23,9 @@ namespace Content.Benchmarks
|
||||
{
|
||||
var random = new Random(3005);
|
||||
|
||||
_colors = new (Color, Color)[N];
|
||||
_output = new Color[N];
|
||||
|
||||
for (var i = 0; i < N; i++)
|
||||
{
|
||||
var r1 = random.NextFloat();
|
||||
@@ -30,123 +38,122 @@ namespace Content.Benchmarks
|
||||
var b2 = random.NextFloat();
|
||||
var a2 = random.NextFloat();
|
||||
|
||||
_colors.Add((new Color(r1, g1, b1, a1), new Color(r2, g2, b2, a2)));
|
||||
_colors[i] = (new Color(r1, g1, b1, a1), new Color(r2, g2, b2, a2));
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void BenchSimple()
|
||||
{
|
||||
foreach (var (a, b) in _colors)
|
||||
for (var i = 0; i < N; i++)
|
||||
{
|
||||
InterpolateSimple(a, b, 0.5f);
|
||||
ref var tuple = ref _colors[i];
|
||||
_output[i] = InterpolateSimple(tuple.Item1, tuple.Item2, 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
//[Benchmark]
|
||||
public void BenchSysVector4()
|
||||
{
|
||||
foreach (var (a, b) in _colors)
|
||||
{
|
||||
InterpolateSysVector4(a, b, 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
//[Benchmark]
|
||||
public void BenchSysVector4Blit()
|
||||
[Benchmark]
|
||||
public void BenchSysVector4In()
|
||||
{
|
||||
foreach (var (a, b) in _colors)
|
||||
for (var i = 0; i < N; i++)
|
||||
{
|
||||
InterpolateSysVector4Blit(a, b, 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
//[Benchmark]
|
||||
public void BenchSysVector4BlitNoException()
|
||||
{
|
||||
foreach (var (a, b) in _colors)
|
||||
{
|
||||
InterpolateSysVector4BlitNoException(a, b, 0.5f);
|
||||
ref var tuple = ref _colors[i];
|
||||
_output[i] = InterpolateSysVector4In(tuple.Item1, tuple.Item2, 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void BenchSysVector4AsRefNoException()
|
||||
public void BenchSysVector4()
|
||||
{
|
||||
foreach (var (a, b) in _colors)
|
||||
for (var i = 0; i < N; i++)
|
||||
{
|
||||
InterpolateSysVector4BlitNoExceptionAsRef(a, b, 0.5f);
|
||||
ref var tuple = ref _colors[i];
|
||||
_output[i] = InterpolateSysVector4(tuple.Item1, tuple.Item2, 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
public static Color InterpolateSimple(Color endPoint1, Color endPoint2, float lambda)
|
||||
#if NETCOREAPP
|
||||
[Benchmark]
|
||||
public void BenchSimd()
|
||||
{
|
||||
for (var i = 0; i < N; i++)
|
||||
{
|
||||
ref var tuple = ref _colors[i];
|
||||
_output[i] = InterpolateSimd(tuple.Item1, tuple.Item2, 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void BenchSimdIn()
|
||||
{
|
||||
for (var i = 0; i < N; i++)
|
||||
{
|
||||
ref var tuple = ref _colors[i];
|
||||
_output[i] = InterpolateSimdIn(tuple.Item1, tuple.Item2, 0.5f);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
public static Color InterpolateSimple(Color a, Color b, float lambda)
|
||||
{
|
||||
if (lambda < 0 || lambda > 1)
|
||||
throw new ArgumentOutOfRangeException(nameof(lambda));
|
||||
return new Color(
|
||||
endPoint1.R * lambda + endPoint2.R * (1 - lambda),
|
||||
endPoint1.G * lambda + endPoint2.G * (1 - lambda),
|
||||
endPoint1.B * lambda + endPoint2.B * (1 - lambda),
|
||||
endPoint1.A * lambda + endPoint2.A * (1 - lambda)
|
||||
a.R + (b.R - a.R) * lambda,
|
||||
a.G + (b.G - a.G) * lambda,
|
||||
a.B + (b.G - a.B) * lambda,
|
||||
a.A + (b.A - a.A) * lambda
|
||||
);
|
||||
}
|
||||
|
||||
public static Color InterpolateSysVector4(Color endPoint1, Color endPoint2, float lambda)
|
||||
{
|
||||
if (lambda < 0 || lambda > 1)
|
||||
throw new ArgumentOutOfRangeException(nameof(lambda));
|
||||
|
||||
var vec1 = new SysVector4(endPoint1.R, endPoint1.G, endPoint1.B, endPoint1.A);
|
||||
var vec2 = new SysVector4(endPoint2.R, endPoint2.G, endPoint2.B, endPoint2.A);
|
||||
|
||||
var res = SysVector4.Lerp(vec1, vec2, 1 - lambda);
|
||||
|
||||
return new Color(
|
||||
res.X, res.Y, res.Z, res.W);
|
||||
}
|
||||
|
||||
public static unsafe Color InterpolateSysVector4Blit(in Color endPoint1, in Color endPoint2, float lambda)
|
||||
{
|
||||
if (lambda < 0 || lambda > 1)
|
||||
throw new ArgumentOutOfRangeException(nameof(lambda));
|
||||
|
||||
|
||||
fixed (Color* p1 = &endPoint1)
|
||||
fixed (Color* p2 = &endPoint2)
|
||||
{
|
||||
var vp1 = (SysVector4*) p1;
|
||||
var vp2 = (SysVector4*) p2;
|
||||
|
||||
var res = SysVector4.Lerp(*vp1, *vp2, 1 - lambda);
|
||||
|
||||
return *(Color*) (&res);
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe Color InterpolateSysVector4BlitNoException(in Color endPoint1, in Color endPoint2,
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
public static Color InterpolateSysVector4(Color a, Color b,
|
||||
float lambda)
|
||||
{
|
||||
fixed (Color* p1 = &endPoint1)
|
||||
fixed (Color* p2 = &endPoint2)
|
||||
{
|
||||
var vp1 = (SysVector4*) p1;
|
||||
var vp2 = (SysVector4*) p2;
|
||||
ref var sva = ref Unsafe.As<Color, SysVector4>(ref a);
|
||||
ref var svb = ref Unsafe.As<Color, SysVector4>(ref b);
|
||||
|
||||
var res = SysVector4.Lerp(*vp2, *vp1, lambda);
|
||||
|
||||
return *(Color*) (&res);
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe Color InterpolateSysVector4BlitNoExceptionAsRef(in Color endPoint1, in Color endPoint2,
|
||||
float lambda)
|
||||
{
|
||||
ref var sv1 = ref Unsafe.As<Color, SysVector4>(ref Unsafe.AsRef(endPoint1));
|
||||
ref var sv2 = ref Unsafe.As<Color, SysVector4>(ref Unsafe.AsRef(endPoint2));
|
||||
|
||||
var res = SysVector4.Lerp(sv2, sv1, lambda);
|
||||
var res = SysVector4.Lerp(sva, svb, lambda);
|
||||
|
||||
return Unsafe.As<SysVector4, Color>(ref res);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
public static Color InterpolateSysVector4In(in Color endPoint1, in Color endPoint2,
|
||||
float lambda)
|
||||
{
|
||||
ref var sva = ref Unsafe.As<Color, SysVector4>(ref Unsafe.AsRef(endPoint1));
|
||||
ref var svb = ref Unsafe.As<Color, SysVector4>(ref Unsafe.AsRef(endPoint2));
|
||||
|
||||
var res = SysVector4.Lerp(svb, sva, lambda);
|
||||
|
||||
return Unsafe.As<SysVector4, Color>(ref res);
|
||||
}
|
||||
|
||||
#if NETCOREAPP
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
public static Color InterpolateSimd(Color a, Color b,
|
||||
float lambda)
|
||||
{
|
||||
var vecA = Unsafe.As<Color, Vector128<float>>(ref a);
|
||||
var vecB = Unsafe.As<Color, Vector128<float>>(ref b);
|
||||
|
||||
vecB = Fma.MultiplyAdd(Sse.Subtract(vecB, vecA), Vector128.Create(lambda), vecA);
|
||||
|
||||
return Unsafe.As<Vector128<float>, Color>(ref vecB);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
public static Color InterpolateSimdIn(in Color a, in Color b,
|
||||
float lambda)
|
||||
{
|
||||
var vecA = Unsafe.As<Color, Vector128<float>>(ref Unsafe.AsRef(a));
|
||||
var vecB = Unsafe.As<Color, Vector128<float>>(ref Unsafe.AsRef(b));
|
||||
|
||||
vecB = Fma.MultiplyAdd(Sse.Subtract(vecB, vecA), Vector128.Create(lambda), vecA);
|
||||
|
||||
return Unsafe.As<Vector128<float>, Color>(ref vecB);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user