From b51860e854e7fc75aa6e421b571609211b580a6a Mon Sep 17 00:00:00 2001 From: Luca Piccioni Date: Wed, 14 Mar 2018 23:37:20 +0100 Subject: [PATCH] Benchmark with BenchmarkDotNet. --- .../OpenGL.Net.Objects.Test_net461.csproj | 1 + OpenGL.Net.Objects.Test/app.config | 35 +++++ OpenGL.Net.Test/Memory.cs | 6 +- ...nchmarkAttribute.cs => MemoryBenchmark.cs} | 61 ++++----- .../OpenGL.Net.Test_monodroid.csproj | 18 ++- OpenGL.Net.Test/OpenGL.Net.Test_net35.csproj | 30 +++- OpenGL.Net.Test/OpenGL.Net.Test_net461.csproj | 128 +++++++++++++++++- OpenGL.Net.Test/TestBaseBenchmark.cs | 70 ---------- OpenGL.Net.Test/app.config | 32 +++++ OpenGL.Net.Test/packages.config | 88 ++++++++---- OpenGL.Net/Memory.cs | 30 ++-- OpenGL.Net/OpenGL.Net_net461.csproj | 5 + OpenGL.Net/packages.config | 1 + .../HelloTriangle.Xamarin.Android.csproj | 2 + 14 files changed, 354 insertions(+), 153 deletions(-) create mode 100644 OpenGL.Net.Objects.Test/app.config rename OpenGL.Net.Test/{BenchmarkAttribute.cs => MemoryBenchmark.cs} (52%) delete mode 100644 OpenGL.Net.Test/TestBaseBenchmark.cs diff --git a/OpenGL.Net.Objects.Test/OpenGL.Net.Objects.Test_net461.csproj b/OpenGL.Net.Objects.Test/OpenGL.Net.Objects.Test_net461.csproj index 052e6b71..9a39777c 100644 --- a/OpenGL.Net.Objects.Test/OpenGL.Net.Objects.Test_net461.csproj +++ b/OpenGL.Net.Objects.Test/OpenGL.Net.Objects.Test_net461.csproj @@ -111,6 +111,7 @@ + diff --git a/OpenGL.Net.Objects.Test/app.config b/OpenGL.Net.Objects.Test/app.config new file mode 100644 index 00000000..6e2ef517 --- /dev/null +++ b/OpenGL.Net.Objects.Test/app.config @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OpenGL.Net.Test/Memory.cs b/OpenGL.Net.Test/Memory.cs index cfb07edc..32fa32f2 100644 --- a/OpenGL.Net.Test/Memory.cs +++ b/OpenGL.Net.Test/Memory.cs @@ -1,5 +1,5 @@  -// Copyright (C) 2016-2017 Luca Piccioni +// Copyright (C) 2016-2018 Luca Piccioni // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -19,14 +19,12 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -using System; - using NUnit.Framework; namespace OpenGL.Test { [TestFixture, Category("Framework")] - internal class MemoryTest + public class MemoryTest { [Test] public void Memory_TestUseSystemCopy() diff --git a/OpenGL.Net.Test/BenchmarkAttribute.cs b/OpenGL.Net.Test/MemoryBenchmark.cs similarity index 52% rename from OpenGL.Net.Test/BenchmarkAttribute.cs rename to OpenGL.Net.Test/MemoryBenchmark.cs index cc36842d..43af1144 100644 --- a/OpenGL.Net.Test/BenchmarkAttribute.cs +++ b/OpenGL.Net.Test/MemoryBenchmark.cs @@ -1,5 +1,5 @@  -// Copyright (C) 2016-2017 Luca Piccioni +// Copyright (C) 2018 Luca Piccioni // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -19,46 +19,43 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -using System; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Attributes.Columns; +using BenchmarkDotNet.Attributes.Jobs; namespace OpenGL.Test { - /// - /// Attribute for marking benchmark methods. - /// - [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] - class BenchmarkAttribute : Attribute + [ClrJob(true), RankColumn] + public class MemoryBenchmarkCopy { - #region Constructors - - /// - /// Construct a BenchmarkAttribute. - /// - /// - /// A that specifies the name of the benchmark. - /// - public BenchmarkAttribute(string name) + [GlobalSetup] + public void Memory_CopyBenchmarkSetup() { - if (name == null) - throw new ArgumentNullException("name"); - - Name = name; + _BenchmarkArraySrc = new byte[ushort.MaxValue]; + _BenchmarkArrayDst = new byte[ushort.MaxValue]; } - #endregion + private byte[] _BenchmarkArraySrc, _BenchmarkArrayDst; - #region Properties + [Params(4, 16, 256, 512, 4096, 8192)] + public int Memory_CopyBenchmarkParams; - /// - /// The name of the benchmark. - /// - public readonly string Name; - - /// - /// Number of repetitions. - /// - public int Repetitions = 1; + [Benchmark()] + public void Memory_CopyBenchmarkSystem() + { + Memory.UseSystemCopy = true; + using (MemoryLock srcLock = new MemoryLock(_BenchmarkArraySrc)) { + Memory.Copy(_BenchmarkArrayDst, srcLock.Address, (ulong)Memory_CopyBenchmarkParams); + } + } - #endregion + [Benchmark] + public void Memory_CopyBenchmarkManaged() + { + Memory.UseSystemCopy = false; + using (MemoryLock srcLock = new MemoryLock(_BenchmarkArraySrc)) { + Memory.Copy(_BenchmarkArrayDst, srcLock.Address, (ulong)Memory_CopyBenchmarkParams); + } + } } } diff --git a/OpenGL.Net.Test/OpenGL.Net.Test_monodroid.csproj b/OpenGL.Net.Test/OpenGL.Net.Test_monodroid.csproj index 647137ab..0baffe3f 100644 --- a/OpenGL.Net.Test/OpenGL.Net.Test_monodroid.csproj +++ b/OpenGL.Net.Test/OpenGL.Net.Test_monodroid.csproj @@ -54,8 +54,24 @@ ..\packages\Xamarin.Forms.1.5.0.6447\lib\MonoAndroid10\FormsViewGroup.dll True + + ..\packages\Microsoft.DotNet.PlatformAbstractions.1.1.2\lib\netstandard1.3\Microsoft.DotNet.PlatformAbstractions.dll + True + + + ..\packages\Microsoft.Extensions.DependencyModel.1.1.0\lib\netstandard1.6\Microsoft.Extensions.DependencyModel.dll + True + + + ..\packages\Microsoft.Extensions.PlatformAbstractions.1.0.0\lib\netstandard1.3\Microsoft.Extensions.PlatformAbstractions.dll + True + + + ..\packages\Newtonsoft.Json.9.0.1\lib\portable-net45+wp80+win8+wpa81\Newtonsoft.Json.dll + True + ..\packages\NUnit.3.6.1\lib\MonoAndroid\nunit.framework.dll True @@ -147,14 +163,12 @@ True Vertex4.tt - - diff --git a/OpenGL.Net.Test/OpenGL.Net.Test_net35.csproj b/OpenGL.Net.Test/OpenGL.Net.Test_net35.csproj index 8af627a1..07179852 100644 --- a/OpenGL.Net.Test/OpenGL.Net.Test_net35.csproj +++ b/OpenGL.Net.Test/OpenGL.Net.Test_net35.csproj @@ -85,6 +85,34 @@ MinimumRecommendedRules.ruleset + + ..\packages\BenchmarkDotNet.Core.0.10.13\lib\net46\BenchmarkDotNet.Core.dll + True + + + ..\packages\BenchmarkDotNet.Toolchains.Roslyn.0.10.13\lib\net46\BenchmarkDotNet.Toolchains.Roslyn.dll + True + + + ..\packages\Microsoft.CodeAnalysis.Common.2.6.1\lib\netstandard1.3\Microsoft.CodeAnalysis.dll + True + + + ..\packages\Microsoft.CodeAnalysis.CSharp.2.6.1\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.dll + True + + + ..\packages\Microsoft.DotNet.InternalAbstractions.1.0.0\lib\net451\Microsoft.DotNet.InternalAbstractions.dll + True + + + ..\packages\Microsoft.DotNet.PlatformAbstractions.1.1.1\lib\net451\Microsoft.DotNet.PlatformAbstractions.dll + True + + + ..\packages\Microsoft.Win32.Registry.4.3.0\lib\net46\Microsoft.Win32.Registry.dll + True + ..\packages\NUnit.3.6.1\lib\net35\nunit.framework.dll True @@ -109,7 +137,6 @@ True ColorRGBA.tt - @@ -149,7 +176,6 @@ - diff --git a/OpenGL.Net.Test/OpenGL.Net.Test_net461.csproj b/OpenGL.Net.Test/OpenGL.Net.Test_net461.csproj index 43966c2c..c09f10e9 100644 --- a/OpenGL.Net.Test/OpenGL.Net.Test_net461.csproj +++ b/OpenGL.Net.Test/OpenGL.Net.Test_net461.csproj @@ -88,24 +88,140 @@ MinimumRecommendedRules.ruleset + + ..\packages\BenchmarkDotNet.0.10.13\lib\net46\BenchmarkDotNet.dll + True + + + ..\packages\BenchmarkDotNet.Core.0.10.13\lib\net46\BenchmarkDotNet.Core.dll + True + + + ..\packages\BenchmarkDotNet.Toolchains.Roslyn.0.10.13\lib\net46\BenchmarkDotNet.Toolchains.Roslyn.dll + True + + + ..\packages\Microsoft.CodeAnalysis.Common.2.6.1\lib\netstandard1.3\Microsoft.CodeAnalysis.dll + True + + + ..\packages\Microsoft.CodeAnalysis.CSharp.2.6.1\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.dll + True + + + + ..\packages\Microsoft.DotNet.InternalAbstractions.1.0.0\lib\net451\Microsoft.DotNet.InternalAbstractions.dll + True + + + ..\packages\Microsoft.DotNet.PlatformAbstractions.1.1.1\lib\net451\Microsoft.DotNet.PlatformAbstractions.dll + True + + + ..\packages\Microsoft.Win32.Registry.4.3.0\lib\net46\Microsoft.Win32.Registry.dll + True + ..\packages\NUnit.3.6.1\lib\net45\nunit.framework.dll True + + ..\packages\System.AppContext.4.3.0\lib\net46\System.AppContext.dll + True + + + ..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + True + + + + ..\packages\System.Console.4.3.0\lib\net46\System.Console.dll + True + + + ..\packages\System.Diagnostics.FileVersionInfo.4.3.0\lib\net46\System.Diagnostics.FileVersionInfo.dll + True + + + ..\packages\System.Diagnostics.StackTrace.4.3.0\lib\net46\System.Diagnostics.StackTrace.dll + True + + + ..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll + True + + + ..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll + True + + + ..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll + True + + ..\packages\System.Numerics.Vectors.4.3.0\lib\net46\System.Numerics.Vectors.dll True - - ..\packages\System.Runtime.CompilerServices.Unsafe.4.3.0\lib\netstandard1.0\System.Runtime.CompilerServices.Unsafe.dll + + ..\packages\System.Reflection.Metadata.1.4.2\lib\portable-net45+win8\System.Reflection.Metadata.dll + True + + + ..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net461\System.Security.Cryptography.Algorithms.dll + True + + + ..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll + True + + + ..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll + True + + + ..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll + True + + + ..\packages\System.Text.Encoding.CodePages.4.3.0\lib\net46\System.Text.Encoding.CodePages.dll + True + + + ..\packages\System.Threading.Tasks.Extensions.4.3.0\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll + True + + + ..\packages\System.Threading.Thread.4.3.0\lib\net46\System.Threading.Thread.dll + True + + + ..\packages\System.ValueTuple.4.3.0\lib\netstandard1.0\System.ValueTuple.dll True + + + ..\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll + True + + + ..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll + True + + + ..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll + True + + + ..\packages\System.Xml.XPath.XDocument.4.3.0\lib\net46\System.Xml.XPath.XDocument.dll + True + @@ -126,6 +242,7 @@ + True @@ -149,14 +266,13 @@ Vertex4.tt - + - @@ -237,6 +353,10 @@ Vertex3.cs + + + + diff --git a/OpenGL.Net.Test/TestBaseBenchmark.cs b/OpenGL.Net.Test/TestBaseBenchmark.cs deleted file mode 100644 index e4b2bacc..00000000 --- a/OpenGL.Net.Test/TestBaseBenchmark.cs +++ /dev/null @@ -1,70 +0,0 @@ - -// Copyright (C) 2016-2017 Luca Piccioni -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Reflection; - -using NUnit.Framework; - -namespace OpenGL.Test -{ - /// - /// Abstract base test creating benchmarking methods. - /// - abstract class TestBaseBenchmark - { - public static void RunBenchmarks(string prefix) where T : class - { - foreach (MethodInfo method in typeof(T).GetMethods(BindingFlags.Static | BindingFlags.Public)) { - if (prefix != null && method.Name.StartsWith(prefix) == false) - continue; - - List benchmarkAttrs = new List(method.GetCustomAttributes(typeof(BenchmarkAttribute), true)); - if (benchmarkAttrs.Count == 0) - continue; - - Run((BenchmarkAttribute)benchmarkAttrs[0], method); - } - } - - /// - /// Run a benchmark. - /// - /// - /// A that specifies the name of the benchmark. - /// - /// - private static void Run(BenchmarkAttribute benchmark, MethodInfo method) - { - Stopwatch crono = new Stopwatch(); - - crono.Start(); - for (int r = 0; r < benchmark.Repetitions; r++) - method.Invoke(null, null); - - crono.Stop(); - - Console.WriteLine("{0}: {1} [ms]", benchmark.Name, crono.ElapsedMilliseconds); - } - } -} diff --git a/OpenGL.Net.Test/app.config b/OpenGL.Net.Test/app.config index 82efe465..36bc143d 100644 --- a/OpenGL.Net.Test/app.config +++ b/OpenGL.Net.Test/app.config @@ -10,6 +10,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OpenGL.Net.Test/packages.config b/OpenGL.Net.Test/packages.config index 91479af6..b9b5dcba 100644 --- a/OpenGL.Net.Test/packages.config +++ b/OpenGL.Net.Test/packages.config @@ -1,57 +1,85 @@  - + + + + + + + + + + + + - - - - - - + + + + + + + + + + + - + + - + - - - - + + + + - + + - - - - - + + + + + + - - - - - - - + + + + + + + + - - + + + + + - - + + + + + + + \ No newline at end of file diff --git a/OpenGL.Net/Memory.cs b/OpenGL.Net/Memory.cs index eb2fb27d..61e15232 100644 --- a/OpenGL.Net/Memory.cs +++ b/OpenGL.Net/Memory.cs @@ -205,15 +205,27 @@ public static void Copy(Array dst, IntPtr src, ulong bytes) /// private static void CopyDelegate_Managed(void *dst, void* src, ulong bytes) { - uint *dstPtr4 = (uint*)dst, srcPtr4 = (uint*)src; - - for (; bytes >= 4; bytes -= 4) - *dstPtr4++ = *srcPtr4++; - - byte *dstPtr1 = (byte*)dstPtr4, srcPtr1 = (byte*)srcPtr4; - - for (; bytes >= 1; bytes -= 1) - *dstPtr1++ = *srcPtr1++; + if (IntPtr.Size == 8) { + // Copy word by word + ulong *dstPtr8 = (ulong*)dst, srcPtr8 = (ulong*)src; + for (; bytes >= 8; bytes -= 8) + *dstPtr8++ = *srcPtr8++; + + // Copy remaining bytes + byte *dstPtr1 = (byte*)dstPtr8, srcPtr1 = (byte*)srcPtr8; + for (; bytes >= 1; bytes -= 1) + *dstPtr1++ = *srcPtr1++; + } else { + // Copy word by word + uint *dstPtr4 = (uint*)dst, srcPtr4 = (uint*)src; + for (; bytes >= 4; bytes -= 4) + *dstPtr4++ = *srcPtr4++; + + // Copy remaining bytes + byte *dstPtr1 = (byte*)dstPtr4, srcPtr1 = (byte*)srcPtr4; + for (; bytes >= 1; bytes -= 1) + *dstPtr1++ = *srcPtr1++; + } } /// diff --git a/OpenGL.Net/OpenGL.Net_net461.csproj b/OpenGL.Net/OpenGL.Net_net461.csproj index 68d4cacb..db66745f 100644 --- a/OpenGL.Net/OpenGL.Net_net461.csproj +++ b/OpenGL.Net/OpenGL.Net_net461.csproj @@ -117,6 +117,11 @@ + + + ..\packages\System.Numerics.Vectors.4.3.0\lib\net46\System.Numerics.Vectors.dll + True + diff --git a/OpenGL.Net/packages.config b/OpenGL.Net/packages.config index 50f9bb67..dbc21343 100644 --- a/OpenGL.Net/packages.config +++ b/OpenGL.Net/packages.config @@ -8,4 +8,5 @@ + \ No newline at end of file diff --git a/Samples/HelloTriangle.Xamarin.Android/HelloTriangle.Xamarin.Android.csproj b/Samples/HelloTriangle.Xamarin.Android/HelloTriangle.Xamarin.Android.csproj index ea89db62..b53bb803 100644 --- a/Samples/HelloTriangle.Xamarin.Android/HelloTriangle.Xamarin.Android.csproj +++ b/Samples/HelloTriangle.Xamarin.Android/HelloTriangle.Xamarin.Android.csproj @@ -29,6 +29,7 @@ 4 True None + C:\Users\Luca\AppData\Local\Temp\vsCCEF.tmp\Debug\ pdbonly @@ -49,6 +50,7 @@ False False False + C:\Users\Luca\AppData\Local\Temp\vsCCEF.tmp\Release\