diff options
Diffstat (limited to 'tests/src/JIT/Performance/CodeQuality/SIMD/ConsoleMandel/ConsoleMandel.cs')
-rw-r--r-- | tests/src/JIT/Performance/CodeQuality/SIMD/ConsoleMandel/ConsoleMandel.cs | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/tests/src/JIT/Performance/CodeQuality/SIMD/ConsoleMandel/ConsoleMandel.cs b/tests/src/JIT/Performance/CodeQuality/SIMD/ConsoleMandel/ConsoleMandel.cs new file mode 100644 index 0000000000..ed7f675700 --- /dev/null +++ b/tests/src/JIT/Performance/CodeQuality/SIMD/ConsoleMandel/ConsoleMandel.cs @@ -0,0 +1,256 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +// + +using Microsoft.Xunit.Performance; +using System; +using System.Diagnostics; +using Xunit; + +[assembly: OptimizeForBenchmarks] +[assembly: MeasureInstructionsRetired] + +namespace ConsoleMandel +{ + public static class Program + { + private const int Pass = 100; + private const int Fail = -1; + private static bool s_silent = false; + + private static void DoNothing(int x, int y, int count) { } + + private static void DrawDot(int x, int y, int count) + { + if (x == 0) + Console.WriteLine(); + Console.Write((count < 1000) ? ' ' : '*'); + } + + private static Algorithms.FractalRenderer.Render GetRenderer(Action<int, int, int> draw, int which) + { + return Algorithms.FractalRenderer.SelectRender(draw, Abort, IsVector(which), IsDouble(which), IsMulti(which), UsesADT(which), !UseIntTypes(which)); + } + + private static bool Abort() { return false; } + + private static bool UseIntTypes(int num) { return (num & 8) == 0; } + + private static bool IsVector(int num) { return num > 7; } + + private static bool IsDouble(int num) { return (num & 4) != 0; } + + private static bool IsMulti(int num) { return (num & 2) != 0; } + + private static bool UsesADT(int num) { return (num & 1) != 0; } + + private static void PrintDescription(int i) + { + Console.WriteLine("{0}: {1} {2}-Precision {3}Threaded using {4} and {5} int types", i, + IsVector(i) ? "Vector" : "Scalar", + IsDouble(i) ? "Double" : "Single", + IsMulti(i) ? "Multi" : "Single", + UsesADT(i) ? "ADT" : "Raw Values", + UseIntTypes(i) ? "using" : "not using any"); + } + + private static void PrintUsage() + { + Console.WriteLine("Usage:\n ConsoleMandel [0-23] -[bench #] where # is the number of iterations."); + for (int i = 0; i < 24; i++) + { + PrintDescription(i); + } + Console.WriteLine("The numeric argument selects the implementation number;"); + Console.WriteLine("If not specified, all are run."); + Console.WriteLine("In non-benchmark mode, dump a text view of the Mandelbrot set."); + Console.WriteLine("In benchmark mode, a larger set is computed but nothing is dumped."); + } + + private static int Main(string[] args) + { + try + { + int which = -1; + bool verbose = false; + bool bench = false; + int iters = 1; + int argNum = 0; + while (argNum < args.Length) + { + if (args[argNum].ToUpperInvariant() == "-BENCH") + { + bench = true; + if ((args.Length <= (argNum + 1)) || !Int32.TryParse(args[argNum + 1], out iters)) + { + iters = 5; + } + argNum++; + } + else if (args[argNum].ToUpperInvariant() == "-V") + { + verbose = true; + } + else if (args[argNum].ToUpperInvariant() == "-S") + { + s_silent = true; + } + else if (!Int32.TryParse(args[argNum], out which)) + { + PrintUsage(); + return Fail; + } + argNum++; + } + if (bench) + { + Bench(iters, which); + return Pass; + } + if (which == -1) + { + PrintUsage(); + return Pass; + } + if (verbose) + { + PrintDescription(which); + } + if (IsVector(which)) + { + if (verbose) + { + Console.WriteLine(" Vector Count is {0}", IsDouble(which) ? System.Numerics.Vector<Double>.Count : System.Numerics.Vector<Single>.Count); + Console.WriteLine(" {0} Accelerated.", System.Numerics.Vector.IsHardwareAccelerated ? "IS" : "IS NOT"); + } + } + var render = GetRenderer(DrawDot, which); + render(-1.5f, .5f, -1f, 1f, 2.0f / 60.0f); + return Pass; + } + catch (System.Exception) + { + return Fail; + } + } + + public static void Bench(int iters, int which) + { + float XC = -1.248f; + float YC = -.0362f; + float Range = .001f; + float xmin = XC - Range; + float xmax = XC + Range; + float ymin = YC - Range; + float ymax = YC + Range; + float step = Range / 1000f; // This will render one million pixels + float warm = Range / 100f; // To warm up, just render 10000 pixels :-) + Algorithms.FractalRenderer.Render[] renderers = new Algorithms.FractalRenderer.Render[24]; + // Warm up each renderer + if (!s_silent) + { + Console.WriteLine("Warming up..."); + } + Stopwatch timer = new Stopwatch(); + int firstRenderer = (which == -1) ? 0 : which; + int lastRenderer = (which == -1) ? (renderers.Length - 1) : which; + for (int i = firstRenderer; i <= lastRenderer; i++) + { + renderers[i] = GetRenderer(DoNothing, i); + timer.Restart(); + renderers[i](xmin, xmax, ymin, ymax, warm); + timer.Stop(); + if (!s_silent) + { + Console.WriteLine("{0}{1}{2}{3}{4} Complete [{5} ms]", + UseIntTypes(i) ? "IntBV " : "Strict ", + IsVector(i) ? "Vector " : "Scalar ", + IsDouble(i) ? "Double " : "Single ", + UsesADT(i) ? "ADT " : "Raw ", + IsMulti(i) ? "Multi " : "Single ", + timer.ElapsedMilliseconds); + } + } + if (!s_silent) + { + Console.WriteLine(" Run Type : Min Max Average Std-Dev"); + } + for (int i = firstRenderer; i <= lastRenderer; i++) + { + long totalTime = 0; + long min = long.MaxValue; + long max = long.MinValue; + for (int count = 0; count < iters; count++) + { + timer.Restart(); + renderers[i](xmin, xmax, ymin, ymax, step); + timer.Stop(); + long time = timer.ElapsedMilliseconds; + max = Math.Max(time, max); + min = Math.Min(time, min); + totalTime += time; + } + double avg = totalTime / (double)iters; + double stdDev = Math.Sqrt(totalTime / (iters - 1.0)) / avg; + if (s_silent) + { + Console.WriteLine("Average: {0,0:0.0}", avg); + } + else + { + Console.WriteLine("{0}{1}{2}{3}{4}: {5,8} {6,8} {7,10:0.0} {8,10:P}", + UseIntTypes(i) ? "IntBV " : "Strict ", + IsVector(i) ? "Vector " : "Scalar ", + IsDouble(i) ? "Double " : "Single ", + UsesADT(i) ? "ADT " : "Raw ", + IsMulti(i) ? "Multi " : "Single ", + min, max, avg, stdDev); + } + } + } + + public static void XBench(int iters, int which) + { + float XC = -1.248f; + float YC = -.0362f; + float Range = .001f; + float xmin = XC - Range; + float xmax = XC + Range; + float ymin = YC - Range; + float ymax = YC + Range; + float step = Range / 100f; + + Algorithms.FractalRenderer.Render renderer = GetRenderer(DoNothing, which); + + for (int count = 0; count < iters; count++) + { + renderer(xmin, xmax, ymin, ymax, step); + } + } + + [Benchmark] + public static void VectorFloatSinglethreadRawNoInt() + { + foreach (var iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + XBench(10, 8); + } + } + } + + [Benchmark] + public static void VectorFloatSinglethreadADTNoInt() + { + foreach (var iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + XBench(10, 9); + } + } + } + } +} |