summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenAuth.Test/Performance/HighPerformance.cs
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2011-05-03 07:49:09 -0700
committerAndrew Arnott <andrewarnott@gmail.com>2011-05-03 07:49:09 -0700
commitb8690062e9ededc3c5d15d246f77ced834b11193 (patch)
treeb6956ebb24337d6195f05eae7c63534e39798576 /src/DotNetOpenAuth.Test/Performance/HighPerformance.cs
parent31f89dffa487e952574c4a68947beba346d38d4d (diff)
downloadDotNetOpenAuth-b8690062e9ededc3c5d15d246f77ced834b11193.zip
DotNetOpenAuth-b8690062e9ededc3c5d15d246f77ced834b11193.tar.gz
DotNetOpenAuth-b8690062e9ededc3c5d15d246f77ced834b11193.tar.bz2
Hid more implementation details of perf measurements.
Diffstat (limited to 'src/DotNetOpenAuth.Test/Performance/HighPerformance.cs')
-rw-r--r--src/DotNetOpenAuth.Test/Performance/HighPerformance.cs114
1 files changed, 111 insertions, 3 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;
+ }
+ }
+ }
+ }
}
}