From 986bb9a5498d1fc0877fd6ee406d918e80b89995 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaarlo=20R=C3=A4ih=C3=A4?= Date: Sat, 21 Apr 2018 19:07:40 +0300 Subject: [PATCH] First BenchmarkDotNetCore addition Add two benchmarks that are run via dotnet core and BenchmarkDotNet --- .../BenchmarkDotNetCore.csproj | 14 ++ BenchmarkDotNetCore/Program.cs | 173 ++++++++++++++++++ BenchmarkDotNetCore/readme.md | 23 +++ 3 files changed, 210 insertions(+) create mode 100644 BenchmarkDotNetCore/BenchmarkDotNetCore.csproj create mode 100644 BenchmarkDotNetCore/Program.cs create mode 100644 BenchmarkDotNetCore/readme.md diff --git a/BenchmarkDotNetCore/BenchmarkDotNetCore.csproj b/BenchmarkDotNetCore/BenchmarkDotNetCore.csproj new file mode 100644 index 0000000..6f55e08 --- /dev/null +++ b/BenchmarkDotNetCore/BenchmarkDotNetCore.csproj @@ -0,0 +1,14 @@ + + + + Exe + netcoreapp2.0 + + + + + + + + + diff --git a/BenchmarkDotNetCore/Program.cs b/BenchmarkDotNetCore/Program.cs new file mode 100644 index 0000000..b74b699 --- /dev/null +++ b/BenchmarkDotNetCore/Program.cs @@ -0,0 +1,173 @@ +using System; +using System.Linq; +using System.Diagnostics; +using FixPointCS; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Running; + +namespace BenchmarkDotNetCore +{ + using ValueGenerator = Func; + + #region Input generator + + class Input + { + public enum SignMode + { + Direct, + Negate, + Random + } + + static public ValueGenerator Uniform(double mn, double mx) + { + return (Random rnd, int count) => + { + double[] values = new double[count]; + for (int i = 0; i < count; i++) + values[i] = mn + (mx - mn) * rnd.NextDouble(); + return values; + }; + } + + static public ValueGenerator Exponential(double mn, double mx, SignMode signMode = SignMode.Direct) + { + Debug.Assert(Math.Sign(mn) == Math.Sign(mx)); + Debug.Assert(Math.Abs(mn) < Math.Abs(mx)); + + double ratio = Math.Log(mx / mn, 2.0); + return (Random rnd, int count) => + { + double[] values = new double[count]; + switch (signMode) + { + case SignMode.Direct: + for (int i = 0; i < count; i++) + values[i] = mn * Math.Pow(2.0, ratio * rnd.NextDouble()); + break; + + case SignMode.Negate: + for (int i = 0; i < count; i++) + values[i] = -mn * Math.Pow(2.0, ratio * rnd.NextDouble()); + break; + + case SignMode.Random: + for (int i = 0; i < count; i++) + values[i] = ((i & 2) - 1) * mn * Math.Pow(2.0, ratio * rnd.NextDouble()); + break; + } + return values; + }; + } + }; + + #endregion // Input generator + + + #region Ceil + + public class CeilFP64vsDouble + { + private const int BENCHMARK_CHUNK_SIZE = 128; + private static readonly Random rnd = new Random(12345678); + + private readonly double[] doubleArrayInputs; + private readonly F64[] f64ArrayInputs; + + private readonly double[] doubleArrayOutputs; + private readonly F64[] f64ArrayOutputs; + + public CeilFP64vsDouble() + { + ValueGenerator inputGenerator = Input.Uniform(-1.0, 1.0); + + this.doubleArrayInputs = inputGenerator(rnd, BENCHMARK_CHUNK_SIZE); + this.f64ArrayInputs = this.doubleArrayInputs.Select(d => F64.FromDouble(d)).ToArray(); + + this.doubleArrayOutputs = new double[BENCHMARK_CHUNK_SIZE]; + this.f64ArrayOutputs = new F64[BENCHMARK_CHUNK_SIZE]; + } + + [Benchmark] + public void FP64Run() + { + for (int i = 0; i < f64ArrayInputs.Length; i++) + { + this.f64ArrayOutputs[i] = this.f64ArrayInputs[i].Ceil(); + } + } + + [Benchmark(Baseline = true)] + public void DoubleRun() + { + for (int i = 0; i < doubleArrayInputs.Length; i++) + { + this.doubleArrayOutputs[i] = Math.Ceiling(this.doubleArrayInputs[i]); + } + } + } + + #endregion // Ceil + + + #region Floor + + public class FloorFP64vsDouble + { + private const int BENCHMARK_CHUNK_SIZE = 128; + private static readonly Random rnd = new Random(12345678); + + private readonly double[] doubleArrayInputs; + private readonly F64[] f64ArrayInputs; + + private readonly double[] doubleArrayOutputs; + private readonly F64[] f64ArrayOutputs; + + public FloorFP64vsDouble() + { + ValueGenerator inputGenerator = Input.Uniform(-1.0, 1.0); + + this.doubleArrayInputs = inputGenerator(rnd, BENCHMARK_CHUNK_SIZE); + this.f64ArrayInputs = this.doubleArrayInputs.Select(d => F64.FromDouble(d)).ToArray(); + + this.doubleArrayOutputs = new double[BENCHMARK_CHUNK_SIZE]; + this.f64ArrayOutputs = new F64[BENCHMARK_CHUNK_SIZE]; + } + + [Benchmark] + public void FP64Run() + { + for (int i = 0; i < f64ArrayInputs.Length; i++) + { + this.f64ArrayOutputs[i] = this.f64ArrayInputs[i].Floor(); + } + } + + [Benchmark(Baseline = true)] + public void DoubleRun() + { + for (int i = 0; i < doubleArrayInputs.Length; i++) + { + this.doubleArrayOutputs[i] = Math.Floor(this.doubleArrayInputs[i]); + } + } + } + + #endregion // Floor + + + public class Program + { + static void Main(string[] args) + { + var switcher = new BenchmarkSwitcher(new[] { + typeof(CeilFP64vsDouble), + typeof(FloorFP64vsDouble) + // If you add another benchmark, please add reference to here + }); + + switcher.Run(args); + } + } +} diff --git a/BenchmarkDotNetCore/readme.md b/BenchmarkDotNetCore/readme.md new file mode 100644 index 0000000..c0c0504 --- /dev/null +++ b/BenchmarkDotNetCore/readme.md @@ -0,0 +1,23 @@ +# Benchmark FixPointCS with BenchmarkDotNet +This project can be used to benchmark FixPointCS C# version with [BenchmarkDotNet](http://benchmarkdotnet.org/). + +## Requirements +* [.NET Core](https://www.microsoft.com/net/download/windows) +* BenchmarkDotNet +* FixPointCS + +## Benchmark guide +1. Make sure you have .NET Core installed (*dotnet --version*) +2. Download the [FixPointCS](https://github.com/XMunkki/FixPointCS) to your computer +3. Move to **BenchmarkDotNet** folder +4. Do dotnet restore (*dotnet restore*) and wait few seconds while additional files are downloaded +5. Run the benchmark you want (Either via *dotnet run -c Release* and select benchmark or provide benchmark as parameter, like *dotnet run -c Release 0*) +6. Wait while benchmark runs and check out results afterwards from console/terminal or from **BenchmarkDotNet.Artifacts\results** folder + +## Development guide + +### Add additional benchmark +You can copy and paste existing code from **Program.cs** file (e.g. *public class CeilFP64vsDouble*) to create new benchmark. You have to also add new entry to the **switcher** variable located in *static void Main(string[] args)* in case you want to run your benchmark via switcher + +### Add something fancy to benchmarks +BenchmarkDotNet does provide many nice features and you can find more help related to BenchmarkDotNet from [the official documentation](http://benchmarkdotnet.org/Guides/GettingStarted.htm) \ No newline at end of file