1
0

ColorInterpolateBenchmark.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #if NETCOREAPP
  2. using System.Runtime.Intrinsics;
  3. using System.Runtime.Intrinsics.X86;
  4. #endif
  5. using System;
  6. using System.Runtime.CompilerServices;
  7. using BenchmarkDotNet.Attributes;
  8. using Robust.Shared.Analyzers;
  9. using Robust.Shared.Maths;
  10. using Robust.Shared.Random;
  11. using SysVector4 = System.Numerics.Vector4;
  12. namespace Content.Benchmarks
  13. {
  14. [DisassemblyDiagnoser]
  15. [Virtual]
  16. public class ColorInterpolateBenchmark
  17. {
  18. #if NETCOREAPP
  19. private const MethodImplOptions AggressiveOpt = MethodImplOptions.AggressiveOptimization;
  20. #else
  21. private const MethodImplOptions AggressiveOpt = default;
  22. #endif
  23. private (Color, Color)[] _colors;
  24. private Color[] _output;
  25. [Params(100)] public int N { get; set; }
  26. [GlobalSetup]
  27. public void Setup()
  28. {
  29. var random = new Random(3005);
  30. _colors = new (Color, Color)[N];
  31. _output = new Color[N];
  32. for (var i = 0; i < N; i++)
  33. {
  34. var r1 = random.NextFloat();
  35. var g1 = random.NextFloat();
  36. var b1 = random.NextFloat();
  37. var a1 = random.NextFloat();
  38. var r2 = random.NextFloat();
  39. var g2 = random.NextFloat();
  40. var b2 = random.NextFloat();
  41. var a2 = random.NextFloat();
  42. _colors[i] = (new Color(r1, g1, b1, a1), new Color(r2, g2, b2, a2));
  43. }
  44. }
  45. [Benchmark]
  46. public void BenchSimple()
  47. {
  48. for (var i = 0; i < N; i++)
  49. {
  50. ref var tuple = ref _colors[i];
  51. _output[i] = InterpolateSimple(tuple.Item1, tuple.Item2, 0.5f);
  52. }
  53. }
  54. [Benchmark]
  55. public void BenchSysVector4In()
  56. {
  57. for (var i = 0; i < N; i++)
  58. {
  59. ref var tuple = ref _colors[i];
  60. _output[i] = InterpolateSysVector4In(tuple.Item1, tuple.Item2, 0.5f);
  61. }
  62. }
  63. [Benchmark]
  64. public void BenchSysVector4()
  65. {
  66. for (var i = 0; i < N; i++)
  67. {
  68. ref var tuple = ref _colors[i];
  69. _output[i] = InterpolateSysVector4(tuple.Item1, tuple.Item2, 0.5f);
  70. }
  71. }
  72. #if NETCOREAPP
  73. [Benchmark]
  74. public void BenchSimd()
  75. {
  76. for (var i = 0; i < N; i++)
  77. {
  78. ref var tuple = ref _colors[i];
  79. _output[i] = InterpolateSimd(tuple.Item1, tuple.Item2, 0.5f);
  80. }
  81. }
  82. [Benchmark]
  83. public void BenchSimdIn()
  84. {
  85. for (var i = 0; i < N; i++)
  86. {
  87. ref var tuple = ref _colors[i];
  88. _output[i] = InterpolateSimdIn(tuple.Item1, tuple.Item2, 0.5f);
  89. }
  90. }
  91. #endif
  92. [MethodImpl(AggressiveOpt)]
  93. public static Color InterpolateSimple(Color a, Color b, float lambda)
  94. {
  95. return new(
  96. a.R + (b.R - a.R) * lambda,
  97. a.G + (b.G - a.G) * lambda,
  98. a.B + (b.G - a.B) * lambda,
  99. a.A + (b.A - a.A) * lambda
  100. );
  101. }
  102. [MethodImpl(AggressiveOpt)]
  103. public static Color InterpolateSysVector4(Color a, Color b,
  104. float lambda)
  105. {
  106. ref var sva = ref Unsafe.As<Color, SysVector4>(ref a);
  107. ref var svb = ref Unsafe.As<Color, SysVector4>(ref b);
  108. var res = SysVector4.Lerp(sva, svb, lambda);
  109. return Unsafe.As<SysVector4, Color>(ref res);
  110. }
  111. [MethodImpl(AggressiveOpt)]
  112. public static Color InterpolateSysVector4In(in Color endPoint1, in Color endPoint2,
  113. float lambda)
  114. {
  115. ref var sva = ref Unsafe.As<Color, SysVector4>(ref Unsafe.AsRef(in endPoint1));
  116. ref var svb = ref Unsafe.As<Color, SysVector4>(ref Unsafe.AsRef(in endPoint2));
  117. var res = SysVector4.Lerp(svb, sva, lambda);
  118. return Unsafe.As<SysVector4, Color>(ref res);
  119. }
  120. #if NETCOREAPP
  121. [MethodImpl(AggressiveOpt)]
  122. public static Color InterpolateSimd(Color a, Color b,
  123. float lambda)
  124. {
  125. var vecA = Unsafe.As<Color, Vector128<float>>(ref a);
  126. var vecB = Unsafe.As<Color, Vector128<float>>(ref b);
  127. vecB = Fma.MultiplyAdd(Sse.Subtract(vecB, vecA), Vector128.Create(lambda), vecA);
  128. return Unsafe.As<Vector128<float>, Color>(ref vecB);
  129. }
  130. [MethodImpl(AggressiveOpt)]
  131. public static Color InterpolateSimdIn(in Color a, in Color b,
  132. float lambda)
  133. {
  134. var vecA = Unsafe.As<Color, Vector128<float>>(ref Unsafe.AsRef(in a));
  135. var vecB = Unsafe.As<Color, Vector128<float>>(ref Unsafe.AsRef(in b));
  136. vecB = Fma.MultiplyAdd(Sse.Subtract(vecB, vecA), Vector128.Create(lambda), vecA);
  137. return Unsafe.As<Vector128<float>, Color>(ref vecB);
  138. }
  139. #endif
  140. }
  141. }