From 0be3925a8c77fd32e9acbf594b772e2908dd98fb Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Mon, 10 Oct 2016 22:43:31 +0200 Subject: [PATCH] Bench: revive benchmarking project, for FFT --- Benchmark.sln | 34 ++ Performance.sln | 38 -- paket.dependencies | 4 +- paket.lock | 23 +- src/Benchmark/Benchmark.csproj | 173 ++++++ src/Benchmark/FFT.cs | 48 ++ .../LinearAlgebra/DenseMatrixProduct.cs | 556 +++++++++++++++++ src/Benchmark/LinearAlgebra/DenseVectorAdd.cs | 149 +++++ src/Benchmark/Program.cs | 35 ++ .../Properties/AssemblyInfo.cs | 0 src/Benchmark/paket.references | 2 + src/Numerics/Numerics.csproj | 1 - .../LinearAlgebra/DenseMatrixProduct.cs | 557 ------------------ .../LinearAlgebra/DenseVectorAdd.cs | 150 ----- src/Performance/Performance.csproj | 109 ---- src/Performance/Program.cs | 52 -- src/Performance/paket.references | 3 - 17 files changed, 1020 insertions(+), 914 deletions(-) create mode 100644 Benchmark.sln delete mode 100644 Performance.sln create mode 100644 src/Benchmark/Benchmark.csproj create mode 100644 src/Benchmark/FFT.cs create mode 100644 src/Benchmark/LinearAlgebra/DenseMatrixProduct.cs create mode 100644 src/Benchmark/LinearAlgebra/DenseVectorAdd.cs create mode 100644 src/Benchmark/Program.cs rename src/{Performance => Benchmark}/Properties/AssemblyInfo.cs (100%) create mode 100644 src/Benchmark/paket.references delete mode 100644 src/Performance/LinearAlgebra/DenseMatrixProduct.cs delete mode 100644 src/Performance/LinearAlgebra/DenseVectorAdd.cs delete mode 100644 src/Performance/Performance.csproj delete mode 100644 src/Performance/Program.cs delete mode 100644 src/Performance/paket.references diff --git a/Benchmark.sln b/Benchmark.sln new file mode 100644 index 00000000..c234ee8a --- /dev/null +++ b/Benchmark.sln @@ -0,0 +1,34 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Benchmark", "src\Benchmark\Benchmark.csproj", "{F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Numerics", "src\Numerics\Numerics.csproj", "{B7CAE5F4-A23F-4438-B5BE-41226618B695}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8DFE7990-CAC9-4BCC-A1D7-F86F0892DD84}" + ProjectSection(SolutionItems) = preProject + paket.dependencies = paket.dependencies + paket.lock = paket.lock + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}.Release|x64.ActiveCfg = Release|x64 + {F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}.Release|x64.Build.0 = Release|x64 + {F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}.Release|x86.ActiveCfg = Release|x64 + {F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}.Release|x86.Build.0 = Release|x64 + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release|x64.ActiveCfg = Release|Any CPU + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release|x64.Build.0 = Release|Any CPU + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release|x86.ActiveCfg = Release|Any CPU + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Performance.sln b/Performance.sln deleted file mode 100644 index 8b734716..00000000 --- a/Performance.sln +++ /dev/null @@ -1,38 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.30723.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Performance", "src\Performance\Performance.csproj", "{F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Numerics", "src\Numerics\Numerics.csproj", "{B7CAE5F4-A23F-4438-B5BE-41226618B695}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release (No MKL)|Any CPU = Release (No MKL)|Any CPU - Release|Any CPU = Release|Any CPU - Release-Signed|Any CPU = Release-Signed|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}.Release (No MKL)|Any CPU.ActiveCfg = Release (No MKL)|Any CPU - {F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}.Release (No MKL)|Any CPU.Build.0 = Release (No MKL)|Any CPU - {F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}.Release|Any CPU.Build.0 = Release|Any CPU - {F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}.Release-Signed|Any CPU.ActiveCfg = Release|Any CPU - {F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}.Release-Signed|Any CPU.Build.0 = Release|Any CPU - {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release (No MKL)|Any CPU.ActiveCfg = Release|Any CPU - {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release (No MKL)|Any CPU.Build.0 = Release|Any CPU - {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release|Any CPU.Build.0 = Release|Any CPU - {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release-Signed|Any CPU.ActiveCfg = Release-Signed|Any CPU - {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release-Signed|Any CPU.Build.0 = Release-Signed|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/paket.dependencies b/paket.dependencies index b36368c4..b23d7690 100644 --- a/paket.dependencies +++ b/paket.dependencies @@ -23,5 +23,5 @@ group Data group Benchmark source http://www.nuget.org/api/v2 - nuget BenchShark 1.0.0 - nuget ConsoleDump 0.6.0.1 + framework: net45 + nuget BenchmarkDotNet diff --git a/paket.lock b/paket.lock index 67ab410a..7344e14e 100644 --- a/paket.lock +++ b/paket.lock @@ -7,10 +7,29 @@ GITHUB src/FsUnit.NUnit/FsUnit.fs (43086ca8981c7642c1067ad5e9de80caf73ba4ec) src/FsUnit.NUnit/FsUnitTyped.fs (43086ca8981c7642c1067ad5e9de80caf73ba4ec) GROUP Benchmark +FRAMEWORK: NET45 NUGET remote: http://www.nuget.org/api/v2 - BenchShark (1.0) - ConsoleDump (0.6.0.1) + BenchmarkDotNet (0.9.9) + BenchmarkDotNet.Toolchains.Roslyn (>= 0.9.9) + BenchmarkDotNet.Core (0.9.9) + System.Threading.Tasks.Extensions (>= 4.0) + BenchmarkDotNet.Toolchains.Roslyn (0.9.9) + BenchmarkDotNet.Core (>= 0.9.9) + Microsoft.CodeAnalysis.CSharp (>= 1.3.2) + System.Threading.Tasks (>= 4.0) + Microsoft.CodeAnalysis.Analyzers (1.1) + Microsoft.CodeAnalysis.Common (1.3.2) + Microsoft.CodeAnalysis.Analyzers (>= 1.1) + System.Collections.Immutable (>= 1.1.37) + System.Reflection.Metadata (>= 1.2) + Microsoft.CodeAnalysis.CSharp (1.3.2) + Microsoft.CodeAnalysis.Common (1.3.2) + System.Collections.Immutable (1.2) + System.Reflection.Metadata (1.2) + System.Collections.Immutable (>= 1.2) + System.Threading.Tasks (4.0.11) + System.Threading.Tasks.Extensions (4.0) GROUP Build NUGET diff --git a/src/Benchmark/Benchmark.csproj b/src/Benchmark/Benchmark.csproj new file mode 100644 index 00000000..36d02609 --- /dev/null +++ b/src/Benchmark/Benchmark.csproj @@ -0,0 +1,173 @@ + + + + + Debug + AnyCPU + {F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E} + Exe + Properties + Benchmark + Benchmark + v4.5 + 512 + + + + + + bin\Release\ + TRACE;NATIVE + true + true + pdbonly + x64 + prompt + MinimumRecommendedRules.ruleset + false + + + bin\Release\ + TRACE;NATIVE + true + true + pdbonly + x86 + prompt + MinimumRecommendedRules.ruleset + true + + + + + + + + + + + + + + + + + + + + + + + + {b7cae5f4-a23f-4438-b5be-41226618b695} + Numerics + + + + + + + + + ..\..\packages\benchmark\BenchmarkDotNet\lib\net45\BenchmarkDotNet.dll + True + True + + + + + + + + + ..\..\packages\benchmark\BenchmarkDotNet.Core\lib\net45\BenchmarkDotNet.Core.dll + True + True + + + True + + + + + + + + + ..\..\packages\benchmark\BenchmarkDotNet.Toolchains.Roslyn\lib\net45\BenchmarkDotNet.Toolchains.Roslyn.dll + True + True + + + + + + + True + + + True + + + + + + + ..\..\packages\benchmark\Microsoft.CodeAnalysis.Common\lib\net45\Microsoft.CodeAnalysis.dll + True + True + + + + + + + + + ..\..\packages\benchmark\Microsoft.CodeAnalysis.CSharp\lib\net45\Microsoft.CodeAnalysis.CSharp.dll + True + True + + + + + + + + + ..\..\packages\benchmark\System.Collections.Immutable\lib\netstandard1.0\System.Collections.Immutable.dll + True + True + + + + + + + + + ..\..\packages\benchmark\System.Reflection.Metadata\lib\netstandard1.1\System.Reflection.Metadata.dll + True + True + + + + + + + + + ..\..\packages\benchmark\System.Threading.Tasks.Extensions\lib\netstandard1.0\System.Threading.Tasks.Extensions.dll + True + True + + + + + \ No newline at end of file diff --git a/src/Benchmark/FFT.cs b/src/Benchmark/FFT.cs new file mode 100644 index 00000000..575130d0 --- /dev/null +++ b/src/Benchmark/FFT.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Numerics; +using BenchmarkDotNet.Attributes; +using MathNet.Numerics; +using MathNet.Numerics.IntegralTransforms; + +namespace Benchmark +{ + public class FFT + { + readonly Dictionary _data = new Dictionary(); + + [Params(64, 65, 4096, 4097, 65536, 65537, 1048576, 1048577)] + public int N { get; set; } + + [Setup] + public void Setup() + { + var realSinusoidal = Generate.Sinusoidal(1048577, 32, -2.0, 2.0); + var imagSawtooth = Generate.Sawtooth(1048577, 32, -20.0, 20.0); + var signal = Generate.Map2(realSinusoidal, imagSawtooth, (r, i) => new Complex(r, i)); + foreach (var n in new[] { 64, 65, 4096, 4097, 65536, 65537, 1048576, 1048577 }) + { + var s = new Complex[n]; + Array.Copy(signal, 0, s, 0, n); + _data[n] = s; + } + + Control.NativeProviderPath = @"C:\Triage\NATIVE-Win\"; + Control.UseNativeMKL(); + } + + [Benchmark(Baseline = true, OperationsPerInvoke = 2)] + public void Managed() + { + Fourier.BluesteinForward(_data[N], FourierOptions.NoScaling); + Fourier.BluesteinInverse(_data[N], FourierOptions.NoScaling); + } + + [Benchmark(OperationsPerInvoke = 2)] + public void NativeMKL() + { + Fourier.Forward(_data[N], FourierOptions.NoScaling); + Fourier.Inverse(_data[N], FourierOptions.NoScaling); + } + } +} diff --git a/src/Benchmark/LinearAlgebra/DenseMatrixProduct.cs b/src/Benchmark/LinearAlgebra/DenseMatrixProduct.cs new file mode 100644 index 00000000..4c8dbe63 --- /dev/null +++ b/src/Benchmark/LinearAlgebra/DenseMatrixProduct.cs @@ -0,0 +1,556 @@ +using System; +using MathNet.Numerics; +using MathNet.Numerics.LinearAlgebra; +using MathNet.Numerics.Providers.LinearAlgebra; +using MathNet.Numerics.Providers.LinearAlgebra.Mkl; +using MathNet.Numerics.Threading; + +namespace Benchmark.LinearAlgebra +{ +// public class DenseMatrixProduct +// { +// readonly int _rounds; +// readonly Matrix _a; +// readonly Matrix _b; + +// readonly ILinearAlgebraProvider _managed = new ManagedLinearAlgebraProvider(); +// readonly ILinearAlgebraProvider _mkl = new MklLinearAlgebraProvider(); +// readonly ILinearAlgebraProvider _safeProvider = new SafeProvider(); +// readonly ILinearAlgebraProvider _unsafeProvider = new UnsafeProvider(); +// readonly ILinearAlgebraProvider _experimentalProvider = new ExperimentalProvider(); + +// public DenseMatrixProduct(int size, int rounds) +// { +// _rounds = rounds; + +// _b = Matrix.Build.Random(size, size); +// _a = Matrix.Build.Random(size, size); + +// _managed.InitializeVerify(); +// _safeProvider.InitializeVerify(); +// _unsafeProvider.InitializeVerify(); +// _experimentalProvider.InitializeVerify(); + +//#if NATIVE +// _mkl.InitializeVerify(); +//#endif +// } + +// public static void Verify(int size) +// { +// var x = new DenseMatrixProduct(size, 1); +// var managedResult = x.ManagedProvider(); +// var mklResult = x.MklProvider(); +// var safeResult = x.SafeProvider(); +// var unsafeResult = x.UnsafeProvider(); +// var experimentalResult = x.ExperimentalProvider(); + +// Console.WriteLine(managedResult.ToString()); +// //Console.WriteLine(mklResult.ToString()); +// //Console.WriteLine(safeResult.ToString()); +// //Console.WriteLine(unsafeResult.ToString()); +// //Console.WriteLine(experimentalResult.ToString()); + +// if (!managedResult.AlmostEqual(mklResult, 1e-12)) +// { +// throw new Exception("MklProvider"); +// } +// if (!managedResult.AlmostEqual(safeResult, 1e-12)) +// { +// throw new Exception("SafeProvider"); +// } +// if (!managedResult.AlmostEqual(unsafeResult, 1e-12)) +// { +// throw new Exception("UnsafeProvider"); +// } +// if (!managedResult.AlmostEqual(experimentalResult, 1e-12)) +// { +// throw new Exception("ExperimentalProvider"); +// } +// } + +// [BenchSharkTask("ManagedProvider")] +// public Matrix ManagedProvider() +// { +// Control.LinearAlgebraProvider = _managed; +// var z = _b; +// for (int i = 0; i < _rounds; i++) +// { +// z = _a*z; +// } +// return z; +// } + +// [BenchSharkTask("MklProvider")] +// public Matrix MklProvider() +// { +// Control.LinearAlgebraProvider = _mkl; +// var z = _b; +// for (int i = 0; i < _rounds; i++) +// { +// z = _a*z; +// } +// return z; +// } + +// [BenchSharkTask("SafeProvider")] +// public Matrix SafeProvider() +// { +// Control.LinearAlgebraProvider = _safeProvider; +// var z = _b; +// for (int i = 0; i < _rounds; i++) +// { +// z = _a*z; +// } +// return z; +// } + +// [BenchSharkTask("UnsafeProvider")] +// public Matrix UnsafeProvider() +// { +// Control.LinearAlgebraProvider = _unsafeProvider; +// var z = _b; +// for (int i = 0; i < _rounds; i++) +// { +// z = _a*z; +// } +// return z; +// } + +// [BenchSharkTask("ExperimentalProvider")] +// public Matrix ExperimentalProvider() +// { +// Control.LinearAlgebraProvider = _experimentalProvider; +// var z = _b; +// for (int i = 0; i < _rounds; i++) +// { +// z = _a*z; +// } +// return z; +// } +// } + +// public class SafeProvider : ManagedLinearAlgebraProvider +// { +// public override void MatrixMultiply(double[] x, int rowsX, int columnsX, double[] y, int rowsY, int columnsY, double[] result) +// { +// if (rowsX + columnsY <= Control.ParallelizeOrder) +// { +// for (int i = 0; i < rowsX; ++i) +// { +// for (int j = 0; j < columnsY; ++j) +// { +// var jrowsY = j*rowsY; +// double sum = 0.0; +// for (int k = 0; k < columnsX; ++k) +// { +// sum += x[k*rowsX + i]*y[jrowsY + k]; +// } +// result[j*rowsX + i] = sum; +// } +// } + +// return; +// } + +// double[] xdata; +// if (ReferenceEquals(x, result)) +// { +// xdata = (double[])x.Clone(); +// } +// else +// { +// xdata = x; +// } + +// double[] ydata; +// if (ReferenceEquals(y, result)) +// { +// ydata = (double[])y.Clone(); +// } +// else +// { +// ydata = y; +// } + +// Array.Clear(result, 0, result.Length); + +// CacheObliviousMatrixMultiply(xdata, 0, 0, ydata, 0, 0, result, 0, 0, rowsX, columnsY, columnsX, rowsX, columnsY, columnsX, 0); +// } + +// public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, double alpha, double[] a, int rowsA, int columnsA, double[] b, int rowsB, int columnsB, double beta, double[] c) +// { +// if (transposeA == Transpose.DontTranspose && transposeB == Transpose.DontTranspose && alpha == 1.0 && beta == 0.0) +// { +// MatrixMultiply(a, rowsA, columnsA, b, rowsB, columnsB, c); +// return; +// } + +// base.MatrixMultiplyWithUpdate(transposeA, transposeB, alpha, a, rowsA, columnsA, b, rowsB, columnsB, beta, c); +// } + +// static void CacheObliviousMatrixMultiply(double[] matrixA, int shiftArow, int shiftAcol, double[] matrixB, int shiftBrow, int shiftBcol, double[] result, int shiftCrow, int shiftCcol, int m, int n, int k, int constM, int constN, int constK, int level) +// { +// if (m + n <= Control.ParallelizeOrder) +// { +// for (var m1 = 0; m1 < m; m1++) +// { +// var matArowPos = m1 + shiftArow; +// var matCrowPos = m1 + shiftCrow; +// for (var n1 = 0; n1 < n; ++n1) +// { +// var boffset = ((n1 + shiftBcol)*constK) + shiftBrow; +// double sum = 0; +// for (var k1 = 0; k1 < k; ++k1) +// { +// sum += matrixA[((k1 + shiftAcol)*constM) + matArowPos]*matrixB[boffset + k1]; +// } + +// result[((n1 + shiftCcol)*constM) + matCrowPos] += sum; +// } +// } + +// return; +// } + +// // divide and conquer +// int m2 = m/2, n2 = n/2, k2 = k/2; + +// level++; +// if (level <= 2) +// { +// CommonParallel.Invoke( +// () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k2, constM, constN, constK, level), +// () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k2, constM, constN, constK, level), +// () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k2, constM, constN, constK, level), +// () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k2, constM, constN, constK, level)); + +// CommonParallel.Invoke( +// () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k - k2, constM, constN, constK, level), +// () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k - k2, constM, constN, constK, level), +// () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k - k2, constM, constN, constK, level), +// () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k - k2, constM, constN, constK, level)); +// } +// else +// { +// CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k2, constM, constN, constK, level); +// CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k2, constM, constN, constK, level); + +// CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k - k2, constM, constN, constK, level); +// CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k - k2, constM, constN, constK, level); + +// CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k2, constM, constN, constK, level); +// CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k2, constM, constN, constK, level); + +// CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k - k2, constM, constN, constK, level); +// CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k - k2, constM, constN, constK, level); +// } +// } +// } + +// public unsafe class UnsafeProvider : ManagedLinearAlgebraProvider +// { +// public override void MatrixMultiply(double[] x, int rowsX, int columnsX, double[] y, int rowsY, int columnsY, double[] result) +// { +// if (rowsX + columnsY <= Control.ParallelizeOrder) +// { +// fixed (double* resultPtr = &result[0]) +// fixed (double* xPtr = &x[0]) +// fixed (double* yPtr = &y[0]) +// { +// double* a = xPtr; +// double* c = resultPtr; +// for (int i = 0; i < rowsX; ++i) +// { +// double* b = yPtr; +// double* cj = c; +// for (int j = 0; j < columnsY; ++j) +// { +// double sum = 0.0; +// for (int k = 0; k < columnsX; ++k) +// { +// sum += a[k*rowsX]*b[k]; +// } +// *cj = sum; +// cj += rowsX; +// b += rowsY; +// } +// a++; +// c++; +// } +// } + +// return; +// } + +// double[] xdata; +// if (ReferenceEquals(x, result)) +// { +// xdata = (double[])x.Clone(); +// } +// else +// { +// xdata = x; +// } + +// double[] ydata; +// if (ReferenceEquals(y, result)) +// { +// ydata = (double[])y.Clone(); +// } +// else +// { +// ydata = y; +// } + +// Array.Clear(result, 0, result.Length); + +// CacheObliviousMatrixMultiply(xdata, 0, 0, ydata, 0, 0, result, 0, 0, rowsX, columnsY, columnsX, rowsX, columnsY, columnsX, 0); +// } + +// public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, double alpha, double[] a, int rowsA, int columnsA, double[] b, int rowsB, int columnsB, double beta, double[] c) +// { +// if (transposeA == Transpose.DontTranspose && transposeB == Transpose.DontTranspose && alpha == 1.0 && beta == 0.0) +// { +// MatrixMultiply(a, rowsA, columnsA, b, rowsB, columnsB, c); +// return; +// } + +// base.MatrixMultiplyWithUpdate(transposeA, transposeB, alpha, a, rowsA, columnsA, b, rowsB, columnsB, beta, c); +// } + +// static void CacheObliviousMatrixMultiply(double[] matrixA, int shiftArow, int shiftAcol, double[] matrixB, int shiftBrow, int shiftBcol, double[] result, int shiftCrow, int shiftCcol, int m, int n, int k, int constM, int constN, int constK, int level) +// { +// if (m + n <= Control.ParallelizeOrder) +// { +// fixed (double* resultPtr = &result[0]) +// fixed (double* aPtr = &matrixA[0]) +// fixed (double* bPtr = &matrixB[0]) +// { +// double* a = aPtr + shiftArow; +// double* c = resultPtr + shiftCrow; +// for (var m1 = 0; m1 < m; m1++) +// { +// for (var n1 = 0; n1 < n; ++n1) +// { +// double* b = bPtr + (n1 + shiftBcol)*constK + shiftBrow; +// double sum = 0; +// for (var k1 = 0; k1 < k; ++k1) +// { +// sum += a[((k1 + shiftAcol)*constM)]*b[k1]; +// } + +// c[((n1 + shiftCcol)*constM)] += sum; +// } +// a++; +// c++; +// } +// } + +// return; +// } + +// // divide and conquer +// int m2 = m/2, n2 = n/2, k2 = k/2; + +// level++; +// if (level <= 2) +// { +// CommonParallel.Invoke( +// () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k2, constM, constN, constK, level), +// () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k2, constM, constN, constK, level), +// () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k2, constM, constN, constK, level), +// () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k2, constM, constN, constK, level)); + +// CommonParallel.Invoke( +// () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k - k2, constM, constN, constK, level), +// () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k - k2, constM, constN, constK, level), +// () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k - k2, constM, constN, constK, level), +// () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k - k2, constM, constN, constK, level)); +// } +// else +// { +// CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k2, constM, constN, constK, level); +// CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k2, constM, constN, constK, level); + +// CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k - k2, constM, constN, constK, level); +// CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k - k2, constM, constN, constK, level); + +// CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k2, constM, constN, constK, level); +// CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k2, constM, constN, constK, level); + +// CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k - k2, constM, constN, constK, level); +// CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k - k2, constM, constN, constK, level); +// } +// } +// } + +// public class ExperimentalProvider : ManagedLinearAlgebraProvider +// { +// public override void MatrixMultiply(double[] x, int rowsX, int columnsX, double[] y, int rowsY, int columnsY, double[] result) +// { +// MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, 1.0, x, rowsX, columnsX, y, rowsY, columnsY, 0.0, result); +// } + +// public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, double alpha, double[] a, int rowsA, int columnsA, double[] b, int rowsB, int columnsB, double beta, double[] c) +// { +// if (a == null) +// { +// throw new ArgumentNullException("a"); +// } + +// if (b == null) +// { +// throw new ArgumentNullException("b"); +// } + +// if (c == null) +// { +// throw new ArgumentNullException("c"); +// } + +// if (transposeA != Transpose.DontTranspose) +// { +// Swap(ref rowsA, ref columnsA); +// } + +// if (transposeB != Transpose.DontTranspose) +// { +// Swap(ref rowsB, ref columnsB); +// } + +// if (columnsA != rowsB) +// { +// throw new ArgumentOutOfRangeException(String.Format("columnsA ({0}) != rowsB ({1})", columnsA, rowsB)); +// } + +// if (rowsA*columnsA != a.Length) +// { +// throw new ArgumentOutOfRangeException(String.Format("rowsA ({0}) * columnsA ({1}) != a.Length ({2})", rowsA, columnsA, a.Length)); +// } + +// if (rowsB*columnsB != b.Length) +// { +// throw new ArgumentOutOfRangeException(String.Format("rowsB ({0}) * columnsB ({1}) != b.Length ({2})", rowsB, columnsB, b.Length)); +// } + +// if (rowsA*columnsB != c.Length) +// { +// throw new ArgumentOutOfRangeException(String.Format("rowsA ({0}) * columnsB ({1}) != c.Length ({2})", rowsA, columnsB, c.Length)); +// } + +// // handle the degenerate cases +// if (beta == 0.0) +// { +// Array.Clear(c, 0, c.Length); +// } +// else if (beta != 1.0) +// { +// ScaleArray(beta, c, c); +// } + +// if (alpha == 0.0) +// { +// return; +// } + +// // Extract column arrays +// var columnDataB = new double[columnsB][]; +// for (int i = 0; i < columnDataB.Length; i++) +// { +// columnDataB[i] = GetColumn(transposeB, i, rowsB, columnsB, b); +// } + +// var shouldNotParallelize = rowsA + columnsB + columnsA < Control.ParallelizeOrder || Control.MaxDegreeOfParallelism < 2; +// if (shouldNotParallelize) +// { +// for (int i = 0; i < rowsA; i++) +// { +// var row = GetRow(transposeA, i, rowsA, columnsA, a); +// for (int j = 0; j < columnsB; j++) +// { +// var col = columnDataB[j]; +// double sum = 0; +// for (int ii = 0; ii < row.Length; ii++) +// { +// sum += row[ii]*col[ii]; +// } + +// c[j*rowsA + i] += alpha*sum; +// } +// } +// } +// else +// { +// CommonParallel.For(0, rowsA, 1, (u, v) => +// { +// for (int i = u; i < v; i++) +// { +// // for each row in a +// var row = GetRow(transposeA, i, rowsA, columnsA, a); +// for (int j = 0; j < columnsB; j++) +// { +// var column = columnDataB[j]; +// double sum = 0; +// for (int ii = 0; ii < row.Length; ii++) +// { +// sum += row[ii]*column[ii]; +// } + +// c[j*rowsA + i] += alpha*sum; +// } +// } +// }); +// } +// } + +// static void Swap(ref int first, ref int second) +// { +// var prior = first; +// first = second; +// second = prior; +// } + +// /// +// /// Assumes that and have already been transposed. +// /// +// static double[] GetRow(Transpose transpose, int rowindx, int numRows, int numCols, double[] matrix) +// { +// var ret = new double[numCols]; +// if (transpose == Transpose.DontTranspose) +// { +// for (int i = 0; i < numCols; i++) +// { +// ret[i] = matrix[(i*numRows) + rowindx]; +// } +// } +// else +// { +// Array.Copy(matrix, rowindx*numCols, ret, 0, numCols); +// } + +// return ret; +// } + +// /// +// /// Assumes that and have already been transposed. +// /// +// static double[] GetColumn(Transpose transpose, int colindx, int numRows, int numCols, double[] matrix) +// { +// var ret = new double[numRows]; +// if (transpose == Transpose.DontTranspose) +// { +// Array.Copy(matrix, colindx*numRows, ret, 0, numRows); +// } +// else +// { +// for (int i = 0; i < numRows; i++) +// { +// ret[i] = matrix[(i*numCols) + colindx]; +// } +// } + +// return ret; +// } +// } +} diff --git a/src/Benchmark/LinearAlgebra/DenseVectorAdd.cs b/src/Benchmark/LinearAlgebra/DenseVectorAdd.cs new file mode 100644 index 00000000..c74efebf --- /dev/null +++ b/src/Benchmark/LinearAlgebra/DenseVectorAdd.cs @@ -0,0 +1,149 @@ +using System; +using MathNet.Numerics; +using MathNet.Numerics.LinearAlgebra; +using MathNet.Numerics.LinearAlgebra.Storage; +using MathNet.Numerics.Providers.LinearAlgebra; +using MathNet.Numerics.Providers.LinearAlgebra.Mkl; +using MathNet.Numerics.Threading; + +namespace Benchmark.LinearAlgebra +{ +// public class DenseVectorAdd +// { +// readonly int _rounds; +// readonly Vector _a; +// readonly Vector _b; + +// readonly ILinearAlgebraProvider _managed = new ManagedLinearAlgebraProvider(); +// readonly ILinearAlgebraProvider _mkl = new MklLinearAlgebraProvider(); + +// public DenseVectorAdd(int size, int rounds) +// { +// _rounds = rounds; + +// _b = Vector.Build.Random(size); +// _a = Vector.Build.Random(size); + +// _managed.InitializeVerify(); +// Control.LinearAlgebraProvider = _managed; + +//#if NATIVE +// _mkl.InitializeVerify(); +//#endif +// } + +// [BenchSharkTask("AddOperator")] +// public Vector AddOperator() +// { +// var z = _b; +// for (int i = 0; i < _rounds; i++) +// { +// z = _a + z; +// } +// return z; +// } + +// [BenchSharkTask("Map2")] +// public Vector Map2() +// { +// var z = _b; +// for (int i = 0; i < _rounds; i++) +// { +// z = _a.Map2((u, v) => u + v, z); +// } +// return z; +// } + +// [BenchSharkTask("Loop")] +// public Vector Loop() +// { +// var z = _b; +// for (int i = 0; i < _rounds; i++) +// { +// var aa = ((DenseVectorStorage)_a.Storage).Data; +// var az = ((DenseVectorStorage)z.Storage).Data; +// var ar = new Double[aa.Length]; +// for (int k = 0; k < ar.Length; k++) +// { +// ar[k] = aa[k] + az[k]; +// } +// z = Vector.Build.Dense(ar); +// } +// return z; +// } + +// [BenchSharkTask("ParallelLoop4096")] +// public Vector ParallelLoop4096() +// { +// var z = _b; +// for (int i = 0; i < _rounds; i++) +// { +// var aa = ((DenseVectorStorage)_a.Storage).Data; +// var az = ((DenseVectorStorage)z.Storage).Data; +// var ar = new Double[aa.Length]; +// CommonParallel.For(0, ar.Length, 4096, (u, v) => +// { +// for (int k = u; k < v; k++) +// { +// ar[k] = aa[k] + az[k]; +// } +// }); +// z = Vector.Build.Dense(ar); +// } +// return z; +// } + +// [BenchSharkTask("ParallelLoop32768")] +// public Vector ParallelLoop32768() +// { +// var z = _b; +// for (int i = 0; i < _rounds; i++) +// { +// var aa = ((DenseVectorStorage)_a.Storage).Data; +// var az = ((DenseVectorStorage)z.Storage).Data; +// var ar = new Double[aa.Length]; +// CommonParallel.For(0, ar.Length, 32768, (u, v) => +// { +// for (int k = u; k < v; k++) +// { +// ar[k] = aa[k] + az[k]; +// } +// }); +// z = Vector.Build.Dense(ar); +// } +// return z; +// } + +// [BenchSharkTask("ManagedProvider")] +// public Vector ManagedProvider() +// { +// var z = _b; +// for (int i = 0; i < _rounds; i++) +// { +// var aa = ((DenseVectorStorage)_a.Storage).Data; +// var az = ((DenseVectorStorage)z.Storage).Data; +// var ar = new Double[aa.Length]; +// _managed.AddArrays(aa, az, ar); +// z = Vector.Build.Dense(ar); +// } +// return z; +// } + +//#if NATIVEMKL +// [BenchSharkTask("MklProvider")] +// public Vector MklProvider() +// { +// var z = _b; +// for (int i = 0; i < _rounds; i++) +// { +// var aa = ((DenseVectorStorage)_a.Storage).Data; +// var az = ((DenseVectorStorage)z.Storage).Data; +// var ar = new Double[aa.Length]; +// _mkl.AddArrays(aa, az, ar); +// z = Vector.Build.Dense(ar); +// } +// return z; +// } +//#endif +// } +} diff --git a/src/Benchmark/Program.cs b/src/Benchmark/Program.cs new file mode 100644 index 00000000..9db81aa6 --- /dev/null +++ b/src/Benchmark/Program.cs @@ -0,0 +1,35 @@ +using System; +using BenchmarkDotNet.Running; +using MathNet.Numerics; + +namespace Benchmark +{ + public class Program + { + public static void Main() + { + //Control.NativeProviderPath = @"..\..\..\..\out\MKL\Windows\"; + Control.NativeProviderPath = @"C:\Triage\NATIVE-Win\"; + + Console.WriteLine("Providers:"); + if (Control.TryUseNativeMKL()) Console.WriteLine(Control.LinearAlgebraProvider); + if (Control.TryUseNativeCUDA()) Console.WriteLine(Control.LinearAlgebraProvider); + if (Control.TryUseNativeOpenBLAS()) Console.WriteLine(Control.LinearAlgebraProvider); + + BenchmarkRunner.Run(); + + //Benchmark(new LinearAlgebra.DenseVectorAdd(10000000,1), 10, "Large (10'000'000) - 10x1 iterations"); + //Benchmark(new LinearAlgebra.DenseVectorAdd(100,1000), 100, "Small (100) - 100x1000 iterations"); + + //DenseMatrixProduct.Verify(5); + //DenseMatrixProduct.Verify(100); + //Benchmark(new DenseMatrixProduct(10,100), 100, "10 - 100x100 iterations"); + //Benchmark(new DenseMatrixProduct(25, 100), 100, "25 - 100x100 iterations"); + //Benchmark(new DenseMatrixProduct(50, 10), 100, "50 - 100x10 iterations"); + //Benchmark(new DenseMatrixProduct(100, 10), 100, "100 - 100x10 iterations"); + //Benchmark(new DenseMatrixProduct(250, 1), 10, "250 - 10x1 iterations"); + //Benchmark(new DenseMatrixProduct(500,1), 10, "500 - 10x1 iterations"); + //Benchmark(new DenseMatrixProduct(1000,1), 2, "1000 - 2x1 iterations"); + } + } +} diff --git a/src/Performance/Properties/AssemblyInfo.cs b/src/Benchmark/Properties/AssemblyInfo.cs similarity index 100% rename from src/Performance/Properties/AssemblyInfo.cs rename to src/Benchmark/Properties/AssemblyInfo.cs diff --git a/src/Benchmark/paket.references b/src/Benchmark/paket.references new file mode 100644 index 00000000..41438b03 --- /dev/null +++ b/src/Benchmark/paket.references @@ -0,0 +1,2 @@ +group Benchmark + BenchmarkDotNet diff --git a/src/Numerics/Numerics.csproj b/src/Numerics/Numerics.csproj index 8a54e767..9f218718 100644 --- a/src/Numerics/Numerics.csproj +++ b/src/Numerics/Numerics.csproj @@ -485,6 +485,5 @@ Resources.Designer.cs - \ No newline at end of file diff --git a/src/Performance/LinearAlgebra/DenseMatrixProduct.cs b/src/Performance/LinearAlgebra/DenseMatrixProduct.cs deleted file mode 100644 index 8f06a07c..00000000 --- a/src/Performance/LinearAlgebra/DenseMatrixProduct.cs +++ /dev/null @@ -1,557 +0,0 @@ -using System; -using Binarysharp.Benchmark; -using MathNet.Numerics; -using MathNet.Numerics.LinearAlgebra; -using MathNet.Numerics.Providers.LinearAlgebra; -using MathNet.Numerics.Providers.LinearAlgebra.Mkl; -using MathNet.Numerics.Threading; - -namespace Performance.LinearAlgebra -{ - public class DenseMatrixProduct - { - readonly int _rounds; - readonly Matrix _a; - readonly Matrix _b; - - readonly ILinearAlgebraProvider _managed = new ManagedLinearAlgebraProvider(); - readonly ILinearAlgebraProvider _mkl = new MklLinearAlgebraProvider(); - readonly ILinearAlgebraProvider _safeProvider = new SafeProvider(); - readonly ILinearAlgebraProvider _unsafeProvider = new UnsafeProvider(); - readonly ILinearAlgebraProvider _experimentalProvider = new ExperimentalProvider(); - - public DenseMatrixProduct(int size, int rounds) - { - _rounds = rounds; - - _b = Matrix.Build.Random(size, size); - _a = Matrix.Build.Random(size, size); - - _managed.InitializeVerify(); - _safeProvider.InitializeVerify(); - _unsafeProvider.InitializeVerify(); - _experimentalProvider.InitializeVerify(); - -#if NATIVE - _mkl.InitializeVerify(); -#endif - } - - public static void Verify(int size) - { - var x = new DenseMatrixProduct(size, 1); - var managedResult = x.ManagedProvider(); - var mklResult = x.MklProvider(); - var safeResult = x.SafeProvider(); - var unsafeResult = x.UnsafeProvider(); - var experimentalResult = x.ExperimentalProvider(); - - Console.WriteLine(managedResult.ToString()); - //Console.WriteLine(mklResult.ToString()); - //Console.WriteLine(safeResult.ToString()); - //Console.WriteLine(unsafeResult.ToString()); - //Console.WriteLine(experimentalResult.ToString()); - - if (!managedResult.AlmostEqual(mklResult, 1e-12)) - { - throw new Exception("MklProvider"); - } - if (!managedResult.AlmostEqual(safeResult, 1e-12)) - { - throw new Exception("SafeProvider"); - } - if (!managedResult.AlmostEqual(unsafeResult, 1e-12)) - { - throw new Exception("UnsafeProvider"); - } - if (!managedResult.AlmostEqual(experimentalResult, 1e-12)) - { - throw new Exception("ExperimentalProvider"); - } - } - - [BenchSharkTask("ManagedProvider")] - public Matrix ManagedProvider() - { - Control.LinearAlgebraProvider = _managed; - var z = _b; - for (int i = 0; i < _rounds; i++) - { - z = _a*z; - } - return z; - } - - [BenchSharkTask("MklProvider")] - public Matrix MklProvider() - { - Control.LinearAlgebraProvider = _mkl; - var z = _b; - for (int i = 0; i < _rounds; i++) - { - z = _a*z; - } - return z; - } - - [BenchSharkTask("SafeProvider")] - public Matrix SafeProvider() - { - Control.LinearAlgebraProvider = _safeProvider; - var z = _b; - for (int i = 0; i < _rounds; i++) - { - z = _a*z; - } - return z; - } - - [BenchSharkTask("UnsafeProvider")] - public Matrix UnsafeProvider() - { - Control.LinearAlgebraProvider = _unsafeProvider; - var z = _b; - for (int i = 0; i < _rounds; i++) - { - z = _a*z; - } - return z; - } - - [BenchSharkTask("ExperimentalProvider")] - public Matrix ExperimentalProvider() - { - Control.LinearAlgebraProvider = _experimentalProvider; - var z = _b; - for (int i = 0; i < _rounds; i++) - { - z = _a*z; - } - return z; - } - } - - public class SafeProvider : ManagedLinearAlgebraProvider - { - public override void MatrixMultiply(double[] x, int rowsX, int columnsX, double[] y, int rowsY, int columnsY, double[] result) - { - if (rowsX + columnsY <= Control.ParallelizeOrder) - { - for (int i = 0; i < rowsX; ++i) - { - for (int j = 0; j < columnsY; ++j) - { - var jrowsY = j*rowsY; - double sum = 0.0; - for (int k = 0; k < columnsX; ++k) - { - sum += x[k*rowsX + i]*y[jrowsY + k]; - } - result[j*rowsX + i] = sum; - } - } - - return; - } - - double[] xdata; - if (ReferenceEquals(x, result)) - { - xdata = (double[])x.Clone(); - } - else - { - xdata = x; - } - - double[] ydata; - if (ReferenceEquals(y, result)) - { - ydata = (double[])y.Clone(); - } - else - { - ydata = y; - } - - Array.Clear(result, 0, result.Length); - - CacheObliviousMatrixMultiply(xdata, 0, 0, ydata, 0, 0, result, 0, 0, rowsX, columnsY, columnsX, rowsX, columnsY, columnsX, 0); - } - - public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, double alpha, double[] a, int rowsA, int columnsA, double[] b, int rowsB, int columnsB, double beta, double[] c) - { - if (transposeA == Transpose.DontTranspose && transposeB == Transpose.DontTranspose && alpha == 1.0 && beta == 0.0) - { - MatrixMultiply(a, rowsA, columnsA, b, rowsB, columnsB, c); - return; - } - - base.MatrixMultiplyWithUpdate(transposeA, transposeB, alpha, a, rowsA, columnsA, b, rowsB, columnsB, beta, c); - } - - static void CacheObliviousMatrixMultiply(double[] matrixA, int shiftArow, int shiftAcol, double[] matrixB, int shiftBrow, int shiftBcol, double[] result, int shiftCrow, int shiftCcol, int m, int n, int k, int constM, int constN, int constK, int level) - { - if (m + n <= Control.ParallelizeOrder) - { - for (var m1 = 0; m1 < m; m1++) - { - var matArowPos = m1 + shiftArow; - var matCrowPos = m1 + shiftCrow; - for (var n1 = 0; n1 < n; ++n1) - { - var boffset = ((n1 + shiftBcol)*constK) + shiftBrow; - double sum = 0; - for (var k1 = 0; k1 < k; ++k1) - { - sum += matrixA[((k1 + shiftAcol)*constM) + matArowPos]*matrixB[boffset + k1]; - } - - result[((n1 + shiftCcol)*constM) + matCrowPos] += sum; - } - } - - return; - } - - // divide and conquer - int m2 = m/2, n2 = n/2, k2 = k/2; - - level++; - if (level <= 2) - { - CommonParallel.Invoke( - () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k2, constM, constN, constK, level), - () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k2, constM, constN, constK, level), - () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k2, constM, constN, constK, level), - () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k2, constM, constN, constK, level)); - - CommonParallel.Invoke( - () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k - k2, constM, constN, constK, level), - () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k - k2, constM, constN, constK, level), - () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k - k2, constM, constN, constK, level), - () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k - k2, constM, constN, constK, level)); - } - else - { - CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k2, constM, constN, constK, level); - CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k2, constM, constN, constK, level); - - CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k - k2, constM, constN, constK, level); - CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k - k2, constM, constN, constK, level); - - CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k2, constM, constN, constK, level); - CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k2, constM, constN, constK, level); - - CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k - k2, constM, constN, constK, level); - CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k - k2, constM, constN, constK, level); - } - } - } - - public unsafe class UnsafeProvider : ManagedLinearAlgebraProvider - { - public override void MatrixMultiply(double[] x, int rowsX, int columnsX, double[] y, int rowsY, int columnsY, double[] result) - { - if (rowsX + columnsY <= Control.ParallelizeOrder) - { - fixed (double* resultPtr = &result[0]) - fixed (double* xPtr = &x[0]) - fixed (double* yPtr = &y[0]) - { - double* a = xPtr; - double* c = resultPtr; - for (int i = 0; i < rowsX; ++i) - { - double* b = yPtr; - double* cj = c; - for (int j = 0; j < columnsY; ++j) - { - double sum = 0.0; - for (int k = 0; k < columnsX; ++k) - { - sum += a[k*rowsX]*b[k]; - } - *cj = sum; - cj += rowsX; - b += rowsY; - } - a++; - c++; - } - } - - return; - } - - double[] xdata; - if (ReferenceEquals(x, result)) - { - xdata = (double[])x.Clone(); - } - else - { - xdata = x; - } - - double[] ydata; - if (ReferenceEquals(y, result)) - { - ydata = (double[])y.Clone(); - } - else - { - ydata = y; - } - - Array.Clear(result, 0, result.Length); - - CacheObliviousMatrixMultiply(xdata, 0, 0, ydata, 0, 0, result, 0, 0, rowsX, columnsY, columnsX, rowsX, columnsY, columnsX, 0); - } - - public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, double alpha, double[] a, int rowsA, int columnsA, double[] b, int rowsB, int columnsB, double beta, double[] c) - { - if (transposeA == Transpose.DontTranspose && transposeB == Transpose.DontTranspose && alpha == 1.0 && beta == 0.0) - { - MatrixMultiply(a, rowsA, columnsA, b, rowsB, columnsB, c); - return; - } - - base.MatrixMultiplyWithUpdate(transposeA, transposeB, alpha, a, rowsA, columnsA, b, rowsB, columnsB, beta, c); - } - - static void CacheObliviousMatrixMultiply(double[] matrixA, int shiftArow, int shiftAcol, double[] matrixB, int shiftBrow, int shiftBcol, double[] result, int shiftCrow, int shiftCcol, int m, int n, int k, int constM, int constN, int constK, int level) - { - if (m + n <= Control.ParallelizeOrder) - { - fixed (double* resultPtr = &result[0]) - fixed (double* aPtr = &matrixA[0]) - fixed (double* bPtr = &matrixB[0]) - { - double* a = aPtr + shiftArow; - double* c = resultPtr + shiftCrow; - for (var m1 = 0; m1 < m; m1++) - { - for (var n1 = 0; n1 < n; ++n1) - { - double* b = bPtr + (n1 + shiftBcol)*constK + shiftBrow; - double sum = 0; - for (var k1 = 0; k1 < k; ++k1) - { - sum += a[((k1 + shiftAcol)*constM)]*b[k1]; - } - - c[((n1 + shiftCcol)*constM)] += sum; - } - a++; - c++; - } - } - - return; - } - - // divide and conquer - int m2 = m/2, n2 = n/2, k2 = k/2; - - level++; - if (level <= 2) - { - CommonParallel.Invoke( - () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k2, constM, constN, constK, level), - () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k2, constM, constN, constK, level), - () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k2, constM, constN, constK, level), - () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k2, constM, constN, constK, level)); - - CommonParallel.Invoke( - () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k - k2, constM, constN, constK, level), - () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k - k2, constM, constN, constK, level), - () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k - k2, constM, constN, constK, level), - () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k - k2, constM, constN, constK, level)); - } - else - { - CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k2, constM, constN, constK, level); - CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k2, constM, constN, constK, level); - - CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k - k2, constM, constN, constK, level); - CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k - k2, constM, constN, constK, level); - - CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k2, constM, constN, constK, level); - CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k2, constM, constN, constK, level); - - CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k - k2, constM, constN, constK, level); - CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k - k2, constM, constN, constK, level); - } - } - } - - public class ExperimentalProvider : ManagedLinearAlgebraProvider - { - public override void MatrixMultiply(double[] x, int rowsX, int columnsX, double[] y, int rowsY, int columnsY, double[] result) - { - MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, 1.0, x, rowsX, columnsX, y, rowsY, columnsY, 0.0, result); - } - - public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, double alpha, double[] a, int rowsA, int columnsA, double[] b, int rowsB, int columnsB, double beta, double[] c) - { - if (a == null) - { - throw new ArgumentNullException("a"); - } - - if (b == null) - { - throw new ArgumentNullException("b"); - } - - if (c == null) - { - throw new ArgumentNullException("c"); - } - - if (transposeA != Transpose.DontTranspose) - { - Swap(ref rowsA, ref columnsA); - } - - if (transposeB != Transpose.DontTranspose) - { - Swap(ref rowsB, ref columnsB); - } - - if (columnsA != rowsB) - { - throw new ArgumentOutOfRangeException(String.Format("columnsA ({0}) != rowsB ({1})", columnsA, rowsB)); - } - - if (rowsA*columnsA != a.Length) - { - throw new ArgumentOutOfRangeException(String.Format("rowsA ({0}) * columnsA ({1}) != a.Length ({2})", rowsA, columnsA, a.Length)); - } - - if (rowsB*columnsB != b.Length) - { - throw new ArgumentOutOfRangeException(String.Format("rowsB ({0}) * columnsB ({1}) != b.Length ({2})", rowsB, columnsB, b.Length)); - } - - if (rowsA*columnsB != c.Length) - { - throw new ArgumentOutOfRangeException(String.Format("rowsA ({0}) * columnsB ({1}) != c.Length ({2})", rowsA, columnsB, c.Length)); - } - - // handle the degenerate cases - if (beta == 0.0) - { - Array.Clear(c, 0, c.Length); - } - else if (beta != 1.0) - { - ScaleArray(beta, c, c); - } - - if (alpha == 0.0) - { - return; - } - - // Extract column arrays - var columnDataB = new double[columnsB][]; - for (int i = 0; i < columnDataB.Length; i++) - { - columnDataB[i] = GetColumn(transposeB, i, rowsB, columnsB, b); - } - - var shouldNotParallelize = rowsA + columnsB + columnsA < Control.ParallelizeOrder || Control.MaxDegreeOfParallelism < 2; - if (shouldNotParallelize) - { - for (int i = 0; i < rowsA; i++) - { - var row = GetRow(transposeA, i, rowsA, columnsA, a); - for (int j = 0; j < columnsB; j++) - { - var col = columnDataB[j]; - double sum = 0; - for (int ii = 0; ii < row.Length; ii++) - { - sum += row[ii]*col[ii]; - } - - c[j*rowsA + i] += alpha*sum; - } - } - } - else - { - CommonParallel.For(0, rowsA, 1, (u, v) => - { - for (int i = u; i < v; i++) - { - // for each row in a - var row = GetRow(transposeA, i, rowsA, columnsA, a); - for (int j = 0; j < columnsB; j++) - { - var column = columnDataB[j]; - double sum = 0; - for (int ii = 0; ii < row.Length; ii++) - { - sum += row[ii]*column[ii]; - } - - c[j*rowsA + i] += alpha*sum; - } - } - }); - } - } - - static void Swap(ref int first, ref int second) - { - var prior = first; - first = second; - second = prior; - } - - /// - /// Assumes that and have already been transposed. - /// - static double[] GetRow(Transpose transpose, int rowindx, int numRows, int numCols, double[] matrix) - { - var ret = new double[numCols]; - if (transpose == Transpose.DontTranspose) - { - for (int i = 0; i < numCols; i++) - { - ret[i] = matrix[(i*numRows) + rowindx]; - } - } - else - { - Array.Copy(matrix, rowindx*numCols, ret, 0, numCols); - } - - return ret; - } - - /// - /// Assumes that and have already been transposed. - /// - static double[] GetColumn(Transpose transpose, int colindx, int numRows, int numCols, double[] matrix) - { - var ret = new double[numRows]; - if (transpose == Transpose.DontTranspose) - { - Array.Copy(matrix, colindx*numRows, ret, 0, numRows); - } - else - { - for (int i = 0; i < numRows; i++) - { - ret[i] = matrix[(i*numCols) + colindx]; - } - } - - return ret; - } - } -} diff --git a/src/Performance/LinearAlgebra/DenseVectorAdd.cs b/src/Performance/LinearAlgebra/DenseVectorAdd.cs deleted file mode 100644 index b6163301..00000000 --- a/src/Performance/LinearAlgebra/DenseVectorAdd.cs +++ /dev/null @@ -1,150 +0,0 @@ -using System; -using Binarysharp.Benchmark; -using MathNet.Numerics; -using MathNet.Numerics.Providers.LinearAlgebra; -using MathNet.Numerics.Providers.LinearAlgebra.Mkl; -using MathNet.Numerics.Threading; -using MathNet.Numerics.LinearAlgebra; -using MathNet.Numerics.LinearAlgebra.Storage; - -namespace Performance.LinearAlgebra -{ - public class DenseVectorAdd - { - readonly int _rounds; - readonly Vector _a; - readonly Vector _b; - - readonly ILinearAlgebraProvider _managed = new ManagedLinearAlgebraProvider(); - readonly ILinearAlgebraProvider _mkl = new MklLinearAlgebraProvider(); - - public DenseVectorAdd(int size, int rounds) - { - _rounds = rounds; - - _b = Vector.Build.Random(size); - _a = Vector.Build.Random(size); - - _managed.InitializeVerify(); - Control.LinearAlgebraProvider = _managed; - -#if NATIVE - _mkl.InitializeVerify(); -#endif - } - - [BenchSharkTask("AddOperator")] - public Vector AddOperator() - { - var z = _b; - for (int i = 0; i < _rounds; i++) - { - z = _a + z; - } - return z; - } - - [BenchSharkTask("Map2")] - public Vector Map2() - { - var z = _b; - for (int i = 0; i < _rounds; i++) - { - z = _a.Map2((u, v) => u + v, z); - } - return z; - } - - [BenchSharkTask("Loop")] - public Vector Loop() - { - var z = _b; - for (int i = 0; i < _rounds; i++) - { - var aa = ((DenseVectorStorage)_a.Storage).Data; - var az = ((DenseVectorStorage)z.Storage).Data; - var ar = new Double[aa.Length]; - for (int k = 0; k < ar.Length; k++) - { - ar[k] = aa[k] + az[k]; - } - z = Vector.Build.Dense(ar); - } - return z; - } - - [BenchSharkTask("ParallelLoop4096")] - public Vector ParallelLoop4096() - { - var z = _b; - for (int i = 0; i < _rounds; i++) - { - var aa = ((DenseVectorStorage)_a.Storage).Data; - var az = ((DenseVectorStorage)z.Storage).Data; - var ar = new Double[aa.Length]; - CommonParallel.For(0, ar.Length, 4096, (u, v) => - { - for (int k = u; k < v; k++) - { - ar[k] = aa[k] + az[k]; - } - }); - z = Vector.Build.Dense(ar); - } - return z; - } - - [BenchSharkTask("ParallelLoop32768")] - public Vector ParallelLoop32768() - { - var z = _b; - for (int i = 0; i < _rounds; i++) - { - var aa = ((DenseVectorStorage)_a.Storage).Data; - var az = ((DenseVectorStorage)z.Storage).Data; - var ar = new Double[aa.Length]; - CommonParallel.For(0, ar.Length, 32768, (u, v) => - { - for (int k = u; k < v; k++) - { - ar[k] = aa[k] + az[k]; - } - }); - z = Vector.Build.Dense(ar); - } - return z; - } - - [BenchSharkTask("ManagedProvider")] - public Vector ManagedProvider() - { - var z = _b; - for (int i = 0; i < _rounds; i++) - { - var aa = ((DenseVectorStorage)_a.Storage).Data; - var az = ((DenseVectorStorage)z.Storage).Data; - var ar = new Double[aa.Length]; - _managed.AddArrays(aa, az, ar); - z = Vector.Build.Dense(ar); - } - return z; - } - -#if NATIVEMKL - [BenchSharkTask("MklProvider")] - public Vector MklProvider() - { - var z = _b; - for (int i = 0; i < _rounds; i++) - { - var aa = ((DenseVectorStorage)_a.Storage).Data; - var az = ((DenseVectorStorage)z.Storage).Data; - var ar = new Double[aa.Length]; - _mkl.AddArrays(aa, az, ar); - z = Vector.Build.Dense(ar); - } - return z; - } -#endif - } -} diff --git a/src/Performance/Performance.csproj b/src/Performance/Performance.csproj deleted file mode 100644 index 328a2d1a..00000000 --- a/src/Performance/Performance.csproj +++ /dev/null @@ -1,109 +0,0 @@ - - - - - Debug - AnyCPU - {F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E} - Exe - Properties - Performance - Performance - v4.5 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - true - x64 - - - pdbonly - true - bin\Release\ - TRACE;NATIVE - prompt - 4 - x64 - true - - - - - - bin\Release\ - TRACE - true - pdbonly - x64 - prompt - MinimumRecommendedRules.ruleset - - - - - - - - - - - - - - - - - - - - - - - {b7cae5f4-a23f-4438-b5be-41226618b695} - Numerics - - - - - libiomp5md.dll - PreserveNewest - - - MathNet.Numerics.MKL.dll - PreserveNewest - - - - - - - ..\..\packages\benchmark\BenchShark\lib\Benchmark.dll - True - True - - - - - - - ..\..\packages\benchmark\ConsoleDump\lib\net40-Client\ConsoleDump.dll - True - True - - - - - \ No newline at end of file diff --git a/src/Performance/Program.cs b/src/Performance/Program.cs deleted file mode 100644 index 78ae3239..00000000 --- a/src/Performance/Program.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using System.Linq; -using Binarysharp.Benchmark; -using ConsoleDump; -using MathNet.Numerics.Statistics; - -namespace Performance -{ - public class Program - { - public static void Main() - { - //Benchmark(new LinearAlgebra.DenseVectorAdd(10000000,1), 10, "Large (10'000'000) - 10x1 iterations"); - //Benchmark(new LinearAlgebra.DenseVectorAdd(100,1000), 100, "Small (100) - 100x1000 iterations"); - - LinearAlgebra.DenseMatrixProduct.Verify(5); - LinearAlgebra.DenseMatrixProduct.Verify(100); - Benchmark(new LinearAlgebra.DenseMatrixProduct(10,100), 100, "10 - 100x100 iterations"); - Benchmark(new LinearAlgebra.DenseMatrixProduct(25, 100), 100, "25 - 100x100 iterations"); - Benchmark(new LinearAlgebra.DenseMatrixProduct(50, 10), 100, "50 - 100x10 iterations"); - Benchmark(new LinearAlgebra.DenseMatrixProduct(100, 10), 100, "100 - 100x10 iterations"); - Benchmark(new LinearAlgebra.DenseMatrixProduct(250, 1), 10, "250 - 10x1 iterations"); - Benchmark(new LinearAlgebra.DenseMatrixProduct(500,1), 10, "500 - 10x1 iterations"); - Benchmark(new LinearAlgebra.DenseMatrixProduct(1000,1), 2, "1000 - 2x1 iterations"); - } - - static void Benchmark(object obj, uint iterations, string suffix = null) - { - var bench = new BenchShark(true); - var result = bench.EvaluateDecoratedTasks(obj, iterations); - var results = result.FastestEvaluations.Select(x => - { - var series = x.Iterations.Select(it => (double)it.ElapsedTicks).ToArray(); - Array.Sort(series); - var summary = SortedArrayStatistics.FiveNumberSummary(series); - var ms = ArrayStatistics.MeanStandardDeviation(series); - return new { x.Name, Mean = ms.Item1, StdDev = ms.Item2, Min = summary[0], Q1 = summary[1], Median = summary[2], Q3 = summary[3], Max = summary[4] }; - }).ToArray(); - var top = results[0]; - var managed = results.Single(x => x.Name.StartsWith("Managed")); - var label = string.IsNullOrEmpty(suffix) ? obj.GetType().FullName : string.Concat(obj.GetType().FullName, ": ", suffix); - results.Select(x => new - { - x.Name, - Mean = Math.Round(x.Mean), StdDev = Math.Round(x.StdDev), - Min = Math.Round(x.Min), Q1 = Math.Round(x.Q1), Median = Math.Round(x.Median), Q3 = Math.Round(x.Q3), Max = Math.Round(x.Max), - TopSlowdown = Math.Round(x.Median/top.Median, 2), - ManagedSpeedup = Math.Round(managed.Median/x.Median, 2) - }).Dump(label); - } - } -} diff --git a/src/Performance/paket.references b/src/Performance/paket.references deleted file mode 100644 index bfbfd966..00000000 --- a/src/Performance/paket.references +++ /dev/null @@ -1,3 +0,0 @@ -group Benchmark - BenchShark - ConsoleDump