Hardware/CPU/GenericCPU.cs
changeset 279 6bce967ba1b5
parent 275 35788ddd1825
child 298 96263190189a
     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();