diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2011-05-03 07:49:09 -0700 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2011-05-03 07:49:09 -0700 |
commit | b8690062e9ededc3c5d15d246f77ced834b11193 (patch) | |
tree | b6956ebb24337d6195f05eae7c63534e39798576 /src/DotNetOpenAuth.Test/Performance | |
parent | 31f89dffa487e952574c4a68947beba346d38d4d (diff) | |
download | DotNetOpenAuth-b8690062e9ededc3c5d15d246f77ced834b11193.zip DotNetOpenAuth-b8690062e9ededc3c5d15d246f77ced834b11193.tar.gz DotNetOpenAuth-b8690062e9ededc3c5d15d246f77ced834b11193.tar.bz2 |
Hid more implementation details of perf measurements.
Diffstat (limited to 'src/DotNetOpenAuth.Test/Performance')
3 files changed, 118 insertions, 129 deletions
diff --git a/src/DotNetOpenAuth.Test/Performance/HighPerformance.cs b/src/DotNetOpenAuth.Test/Performance/HighPerformance.cs index 32b4cfa..7488d56 100644 --- a/src/DotNetOpenAuth.Test/Performance/HighPerformance.cs +++ b/src/DotNetOpenAuth.Test/Performance/HighPerformance.cs @@ -6,7 +6,9 @@ namespace DotNetOpenAuth.Test.Performance { using System; + using System.ComponentModel; using System.Diagnostics; + using System.Runtime.InteropServices; using System.Threading; using log4net; using NUnit.Framework; @@ -24,7 +26,7 @@ namespace DotNetOpenAuth.Test.Performance { /// Initializes a new instance of the <see cref="HighPerformance"/> class. /// </summary> internal HighPerformance() { - if (!PerformanceTestUtilities.CoolOff()) { + if (!WaitForQuietCpu()) { Assert.Inconclusive("Timed out waiting for a quiet CPU in which to perform perf tests."); } @@ -34,7 +36,7 @@ namespace DotNetOpenAuth.Test.Performance { this.originalProcessPriority = Process.GetCurrentProcess().PriorityClass; Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High; Thread.CurrentThread.Priority = ThreadPriority.Highest; - HighCpu(); + SpinCpu(); } /// <summary> @@ -51,7 +53,7 @@ namespace DotNetOpenAuth.Test.Performance { /// <summary> /// Runs the CPU in a tight loop to get it out of any low power state. /// </summary> - private static void HighCpu() { + private static void SpinCpu() { int dummy; new MultiSampleCodeTimer(10, 1000).Measure( "Loop 1K times", @@ -65,5 +67,111 @@ namespace DotNetOpenAuth.Test.Performance { dummy = k; // avoid optimization. }); } + + private static bool WaitForQuietCpu(float maxCpuSpike = 10, int minSecondsOfQuiet = 2, int maxSecondsBeforeGiveUp = 30) { + using (var pc = new System.Diagnostics.PerformanceCounter()) { + pc.CategoryName = "Processor"; + pc.CounterName = "% Processor Time"; + pc.InstanceName = "_Total"; + + TimeSpan samplingInterval = TimeSpan.FromMilliseconds(1000); + TimeSpan minimumQuietTime = TimeSpan.FromSeconds(minSecondsOfQuiet); + TimeSpan maximumTimeBeforeBail = TimeSpan.FromSeconds(maxSecondsBeforeGiveUp); + DateTime startTryingStamp = DateTime.Now; + int hitsRequired = (int)(minimumQuietTime.TotalMilliseconds / samplingInterval.TotalMilliseconds); + while (DateTime.Now - startTryingStamp < maximumTimeBeforeBail) { + int hits; + for (hits = 0; hits < hitsRequired; hits++) { + float currentCpuUtilization = pc.NextValue(); + if (currentCpuUtilization > maxCpuSpike) { + ////Console.WriteLine("Miss: CPU at {0}% utilization", currentCpuUtilization); + break; + } + + ////Console.WriteLine("Hit: CPU at {0}% utilization", currentCpuUtilization); + Thread.Sleep(samplingInterval); + } + + if (hits == hitsRequired) { + return true; + } + + Thread.Sleep(samplingInterval); + } + + return false; + } + } + + /// <summary> + /// PowerManagement allows you to access the funtionality of the Control Panel -> Power Options + /// dialog in windows. (Currently we only use VISTA APIs). + /// </summary> + private static class PowerManagment { + internal static unsafe Guid CurrentPolicy { + get { + Guid* retPolicy = null; + Guid ret = Guid.Empty; + try { + int callRet = PowerGetActiveScheme(IntPtr.Zero, ref retPolicy); + if (callRet == 0) { + ret = *retPolicy; + Marshal.FreeHGlobal((IntPtr)retPolicy); + } + } catch (Exception) { + } + return ret; + } + + set { + Guid newPolicy = value; + int result = PowerSetActiveScheme(IntPtr.Zero, ref newPolicy); + if (result != 0) { + throw new Win32Exception(result); + } + } + } + + [DllImport("powrprof.dll")] + private static unsafe extern int PowerGetActiveScheme(IntPtr reservedZero, ref Guid* policyGuidRet); + + [DllImport("powrprof.dll")] + private static extern int PowerSetActiveScheme(IntPtr reservedZero, ref Guid policyGuid); + + internal static class PowerProfiles { + internal static Guid HighPerformance = new Guid(0x8c5e7fda, 0xe8bf, 0x4a96, 0x9a, 0x85, 0xa6, 0xe2, 0x3a, 0x8c, 0x63, 0x5c); + + internal static Guid Balanced = new Guid(0x381b4222, 0xf694, 0x41f0, 0x96, 0x85, 0xff, 0x5b, 0xb2, 0x60, 0xdf, 0x2e); + + internal static Guid PowerSaver = new Guid(0xa1841308, 0x3541, 0x4fab, 0xbc, 0x81, 0xf7, 0x15, 0x56, 0xf2, 0x0b, 0x4a); + } + + internal class PowerSetting : IDisposable { + /// <summary> + /// The power policy in effect when this instance was constructed. + /// </summary> + private Guid previousPolicy; + + /// <summary> + /// Initializes a new instance of the <see cref="PowerSetting"/> class. + /// </summary> + /// <param name="powerProfile">The power profile.</param> + internal PowerSetting(Guid powerProfile) { + this.previousPolicy = PowerManagment.CurrentPolicy; + if (this.previousPolicy != powerProfile) { + PowerManagment.CurrentPolicy = powerProfile; + } + } + + /// <summary> + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// </summary> + public void Dispose() { + if (this.previousPolicy != PowerManagment.CurrentPolicy) { + PowerManagment.CurrentPolicy = this.previousPolicy; + } + } + } + } } } diff --git a/src/DotNetOpenAuth.Test/Performance/PerformanceTestUtilities.cs b/src/DotNetOpenAuth.Test/Performance/PerformanceTestUtilities.cs index 33a177a..1b747aa 100644 --- a/src/DotNetOpenAuth.Test/Performance/PerformanceTestUtilities.cs +++ b/src/DotNetOpenAuth.Test/Performance/PerformanceTestUtilities.cs @@ -13,18 +13,13 @@ namespace DotNetOpenAuth.Test.Performance { using NUnit.Framework; internal static class PerformanceTestUtilities { - internal static Stats Baseline; + private static Stats baseline; static PerformanceTestUtilities() { - Baseline = CollectBaseline(); + baseline = CollectBaseline(); TestUtilities.TestLogger.InfoFormat( "Scaled where EmptyStaticFunction = 1.0 ({0:f1} nsec = 1.0 units)", - Baseline.Median * 1000); - } - - internal static bool IsOptimized(Assembly assembly) { - DebuggableAttribute debugAttribute = (DebuggableAttribute)System.Attribute.GetCustomAttribute(assembly, typeof(System.Diagnostics.DebuggableAttribute)); - return debugAttribute == null || !debugAttribute.IsJITOptimizerDisabled; + baseline.Median * 1000); } internal static Stats Measure(Action action, float maximumAllowedUnitTime, int samples = 10, int iterations = 100, string name = null) { @@ -38,7 +33,7 @@ namespace DotNetOpenAuth.Test.Performance { stats = timer.Measure(name ?? TestContext.CurrentContext.Test.FullName, action); } - stats.AdjustForScale(PerformanceTestUtilities.Baseline.Median); + stats.AdjustForScale(PerformanceTestUtilities.baseline.Median); TestUtilities.TestLogger.InfoFormat( "Performance counters: median {0}, mean {1}, min {2}, max {3}, stddev {4} ({5}%).", @@ -55,40 +50,9 @@ namespace DotNetOpenAuth.Test.Performance { return stats; } - internal static bool CoolOff() { - using (var pc = new System.Diagnostics.PerformanceCounter()) { - pc.CategoryName = "Processor"; - pc.CounterName = "% Processor Time"; - pc.InstanceName = "_Total"; - - TimeSpan samplingInterval = TimeSpan.FromMilliseconds(1000); - TimeSpan minimumQuietTime = TimeSpan.FromSeconds(2); - TimeSpan maximumTimeBeforeBail = TimeSpan.FromSeconds(30); - float maximumCpuUtilization = 10; - DateTime startTryingStamp = DateTime.Now; - int hitsRequired = (int)(minimumQuietTime.TotalMilliseconds / samplingInterval.TotalMilliseconds); - while (DateTime.Now - startTryingStamp < maximumTimeBeforeBail) { - int hits; - for (hits = 0; hits < hitsRequired; hits++) { - float currentCpuUtilization = pc.NextValue(); - if (currentCpuUtilization > maximumCpuUtilization) { - ////Console.WriteLine("Miss: CPU at {0}% utilization", currentCpuUtilization); - break; - } - - ////Console.WriteLine("Hit: CPU at {0}% utilization", currentCpuUtilization); - Thread.Sleep(samplingInterval); - } - - if (hits == hitsRequired) { - return true; - } - - Thread.Sleep(samplingInterval); - } - - return false; - } + private static bool IsOptimized(Assembly assembly) { + DebuggableAttribute debugAttribute = (DebuggableAttribute)System.Attribute.GetCustomAttribute(assembly, typeof(System.Diagnostics.DebuggableAttribute)); + return debugAttribute == null || !debugAttribute.IsJITOptimizerDisabled; } private static Stats CollectBaseline() { diff --git a/src/DotNetOpenAuth.Test/Performance/PowerManagement.cs b/src/DotNetOpenAuth.Test/Performance/PowerManagement.cs deleted file mode 100644 index 81c6e7a..0000000 --- a/src/DotNetOpenAuth.Test/Performance/PowerManagement.cs +++ /dev/null @@ -1,83 +0,0 @@ -//----------------------------------------------------------------------- -// <copyright file="PowerManagement.cs" company="Andrew Arnott"> -// Copyright (c) Andrew Arnott. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.Test.Performance { - using System; - using System.ComponentModel; - using System.Diagnostics; - using System.Runtime.InteropServices; - - /// <summary> - /// PowerManagement allows you to access the funtionality of the Control Panel -> Power Options - /// dialog in windows. (Currently we only use VISTA APIs). - /// </summary> - internal static class PowerManagment { - internal static unsafe Guid CurrentPolicy { - get { - Guid* retPolicy = null; - Guid ret = Guid.Empty; - try { - int callRet = PowerGetActiveScheme(IntPtr.Zero, ref retPolicy); - if (callRet == 0) { - ret = *retPolicy; - Marshal.FreeHGlobal((IntPtr)retPolicy); - } - } catch (Exception) { - } - return ret; - } - - set { - Guid newPolicy = value; - int result = PowerSetActiveScheme(IntPtr.Zero, ref newPolicy); - if (result != 0) { - throw new Win32Exception(result); - } - } - } - - [DllImport("powrprof.dll")] - private static unsafe extern int PowerGetActiveScheme(IntPtr reservedZero, ref Guid* policyGuidRet); - - [DllImport("powrprof.dll")] - private static extern int PowerSetActiveScheme(IntPtr reservedZero, ref Guid policyGuid); - - internal static class PowerProfiles { - internal static Guid HighPerformance = new Guid(0x8c5e7fda, 0xe8bf, 0x4a96, 0x9a, 0x85, 0xa6, 0xe2, 0x3a, 0x8c, 0x63, 0x5c); - - internal static Guid Balanced = new Guid(0x381b4222, 0xf694, 0x41f0, 0x96, 0x85, 0xff, 0x5b, 0xb2, 0x60, 0xdf, 0x2e); - - internal static Guid PowerSaver = new Guid(0xa1841308, 0x3541, 0x4fab, 0xbc, 0x81, 0xf7, 0x15, 0x56, 0xf2, 0x0b, 0x4a); - } - - internal class PowerSetting : IDisposable { - /// <summary> - /// The power policy in effect when this instance was constructed. - /// </summary> - private Guid previousPolicy; - - /// <summary> - /// Initializes a new instance of the <see cref="PowerSetting"/> class. - /// </summary> - /// <param name="powerProfile">The power profile.</param> - internal PowerSetting(Guid powerProfile) { - this.previousPolicy = PowerManagment.CurrentPolicy; - if (this.previousPolicy != powerProfile) { - PowerManagment.CurrentPolicy = powerProfile; - } - } - - /// <summary> - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// </summary> - public void Dispose() { - if (this.previousPolicy != PowerManagment.CurrentPolicy) { - PowerManagment.CurrentPolicy = this.previousPolicy; - } - } - } - } -}
\ No newline at end of file |