1.1 --- a/Hardware/CPU/GenericCPU.cs Tue May 03 18:20:06 2011 +0000
1.2 +++ b/Hardware/CPU/GenericCPU.cs Sun May 08 22:10:13 2011 +0000
1.3 @@ -60,10 +60,12 @@
1.4 private readonly bool hasTimeStampCounter;
1.5 private readonly bool isInvariantTimeStampCounter;
1.6 private readonly double estimatedTimeStampCounterFrequency;
1.7 + private readonly double estimatedTimeStampCounterFrequencyError;
1.8
1.9 private ulong lastTimeStampCount;
1.10 private long lastTime;
1.11 - private double timeStampCounterFrequency;
1.12 + private double timeStampCounterFrequency;
1.13 +
1.14
1.15 private readonly Vendor vendor;
1.16
1.17 @@ -132,9 +134,10 @@
1.18
1.19 if (hasTimeStampCounter) {
1.20 ulong mask = ThreadAffinity.Set(1UL << cpuid[0][0].Thread);
1.21 -
1.22 - estimatedTimeStampCounterFrequency =
1.23 - EstimateTimeStampCounterFrequency();
1.24 +
1.25 + EstimateTimeStampCounterFrequency(
1.26 + out estimatedTimeStampCounterFrequency,
1.27 + out estimatedTimeStampCounterFrequencyError);
1.28
1.29 ThreadAffinity.Set(mask);
1.30 } else {
1.31 @@ -157,34 +160,55 @@
1.32 processorIndex.ToString(CultureInfo.InvariantCulture));
1.33 }
1.34
1.35 - private static double EstimateTimeStampCounterFrequency() {
1.36 + private void EstimateTimeStampCounterFrequency(out double frequency,
1.37 + out double error)
1.38 + {
1.39 + double f, e;
1.40 +
1.41 // preload the function
1.42 - EstimateTimeStampCounterFrequency(0);
1.43 - EstimateTimeStampCounterFrequency(0);
1.44 + EstimateTimeStampCounterFrequency(0, out f, out e);
1.45 + EstimateTimeStampCounterFrequency(0, out f, out e);
1.46
1.47 - // estimate the frequency in MHz
1.48 - List<double> estimatedFrequency = new List<double>(3);
1.49 - for (int i = 0; i < 3; i++)
1.50 - estimatedFrequency.Add(1e-6 * EstimateTimeStampCounterFrequency(0.025));
1.51 -
1.52 - estimatedFrequency.Sort();
1.53 - return estimatedFrequency[1];
1.54 + // estimate the frequency
1.55 + error = double.MaxValue;
1.56 + frequency = 0;
1.57 + for (int i = 0; i < 5; i++) {
1.58 + EstimateTimeStampCounterFrequency(0.025, out f, out e);
1.59 + if (e < error) {
1.60 + error = e;
1.61 + frequency = f;
1.62 + }
1.63 +
1.64 + if (error < 1e-4)
1.65 + break;
1.66 + }
1.67 }
1.68
1.69 - private static double EstimateTimeStampCounterFrequency(double timeWindow) {
1.70 + private void EstimateTimeStampCounterFrequency(double timeWindow,
1.71 + out double frequency, out double error)
1.72 + {
1.73 long ticks = (long)(timeWindow * Stopwatch.Frequency);
1.74 ulong countBegin, countEnd;
1.75
1.76 long timeBegin = Stopwatch.GetTimestamp() +
1.77 (long)Math.Ceiling(0.001 * ticks);
1.78 long timeEnd = timeBegin + ticks;
1.79 +
1.80 while (Stopwatch.GetTimestamp() < timeBegin) { }
1.81 countBegin = Opcode.Rdtsc();
1.82 + long afterBegin = Stopwatch.GetTimestamp();
1.83 +
1.84 while (Stopwatch.GetTimestamp() < timeEnd) { }
1.85 countEnd = Opcode.Rdtsc();
1.86 + long afterEnd = Stopwatch.GetTimestamp();
1.87
1.88 - return (((double)(countEnd - countBegin)) * Stopwatch.Frequency) /
1.89 - (timeEnd - timeBegin);
1.90 + double delta = (timeEnd - timeBegin);
1.91 + frequency = 1e-6 *
1.92 + (((double)(countEnd - countBegin)) * Stopwatch.Frequency) / delta;
1.93 +
1.94 + double beginError = (afterBegin - timeBegin) / delta;
1.95 + double endError = (afterEnd - timeEnd) / delta;
1.96 + error = beginError + endError;
1.97 }
1.98
1.99
1.100 @@ -225,6 +249,13 @@
1.101 r.AppendLine("Time Stamp Counter: " + (hasTimeStampCounter ? (
1.102 isInvariantTimeStampCounter ? "Invariant" : "Not Invariant") : "None"));
1.103 r.AppendLine(string.Format(CultureInfo.InvariantCulture,
1.104 + "Estimated Time Stamp Counter Frequency: {0} MHz",
1.105 + Math.Round(estimatedTimeStampCounterFrequency * 100) * 0.01));
1.106 + r.AppendLine(string.Format(CultureInfo.InvariantCulture,
1.107 + "Estimated Time Stamp Counter Frequency Error: {0} Mhz",
1.108 + Math.Round(estimatedTimeStampCounterFrequency *
1.109 + estimatedTimeStampCounterFrequencyError * 1e5) * 1e-5));
1.110 + r.AppendLine(string.Format(CultureInfo.InvariantCulture,
1.111 "Time Stamp Counter Frequency: {0} MHz",
1.112 Math.Round(timeStampCounterFrequency * 100) * 0.01));
1.113 r.AppendLine();