Reading the timeStampCounterMultiplier right at the beginning when the time stamp counter is estimated instead of reading it at each update. Refactored the IntelCPU code a bit.
authormoel.mich
Sun, 10 Oct 2010 16:57:11 +0000
changeset 219ce04404774d6
parent 218 194186efdde9
child 220 e51749b206ee
Reading the timeStampCounterMultiplier right at the beginning when the time stamp counter is estimated instead of reading it at each update. Refactored the IntelCPU code a bit.
Hardware/CPU/IntelCPU.cs
Properties/AssemblyVersion.cs
     1.1 --- a/Hardware/CPU/IntelCPU.cs	Fri Oct 08 12:18:32 2010 +0000
     1.2 +++ b/Hardware/CPU/IntelCPU.cs	Sun Oct 10 16:57:11 2010 +0000
     1.3 @@ -36,16 +36,25 @@
     1.4  */
     1.5  
     1.6  using System;
     1.7 -using System.Collections.Generic;
     1.8 +using System.Globalization;
     1.9 +using System.Text;
    1.10  
    1.11  namespace OpenHardwareMonitor.Hardware.CPU {
    1.12    internal sealed class IntelCPU : GenericCPU {
    1.13  
    1.14 +    private enum Microarchitecture {
    1.15 +      Unknown,
    1.16 +      Core,
    1.17 +      Atom,
    1.18 +      Nehalem
    1.19 +    }
    1.20 +
    1.21      private readonly Sensor[] coreTemperatures;
    1.22      private readonly Sensor[] coreClocks;
    1.23      private readonly Sensor busClock;
    1.24  
    1.25 -    private readonly uint maxNehalemMultiplier;
    1.26 +    private readonly Microarchitecture microarchitecture;
    1.27 +    private readonly double timeStampCounterMultiplier;
    1.28  
    1.29      private const uint IA32_THERM_STATUS_MSR = 0x019C;
    1.30      private const uint IA32_TEMPERATURE_TARGET = 0x01A2;
    1.31 @@ -62,11 +71,13 @@
    1.32      public IntelCPU(int processorIndex, CPUID[][] cpuid, ISettings settings)
    1.33        : base(processorIndex, cpuid, settings) 
    1.34      {
    1.35 +      // set tjMax
    1.36        float[] tjMax;
    1.37        switch (family) {
    1.38          case 0x06: {
    1.39              switch (model) {
    1.40 -              case 0x0F: // Intel Core (65nm)
    1.41 +              case 0x0F: // Intel Core 2 (65nm)
    1.42 +                microarchitecture = Microarchitecture.Core;
    1.43                  switch (stepping) {
    1.44                    case 0x06: // B2
    1.45                      switch (coreCount) {
    1.46 @@ -85,9 +96,11 @@
    1.47                    default:
    1.48                      tjMax = Floats(85 + 10); break;
    1.49                  } break;
    1.50 -              case 0x17: // Intel Core (45nm)
    1.51 +              case 0x17: // Intel Core 2 (45nm)
    1.52 +                microarchitecture = Microarchitecture.Core;
    1.53                  tjMax = Floats(100); break;
    1.54                case 0x1C: // Intel Atom (45nm)
    1.55 +                microarchitecture = Microarchitecture.Atom;
    1.56                  switch (stepping) {
    1.57                    case 0x02: // C0
    1.58                      tjMax = Floats(90); break;
    1.59 @@ -100,6 +113,7 @@
    1.60                case 0x1E: // Intel Core i5, i7 LGA1156 (45nm)
    1.61                case 0x25: // Intel Core i3, i5, i7 LGA1156 (32nm)
    1.62                case 0x2C: // Intel Core i7 LGA1366 (32nm) 6 Core
    1.63 +                microarchitecture = Microarchitecture.Nehalem;
    1.64                  uint eax, edx;
    1.65                  tjMax = new float[coreCount];
    1.66                  for (int i = 0; i < coreCount; i++) {
    1.67 @@ -109,16 +123,39 @@
    1.68                    } else {
    1.69                      tjMax[i] = 100;
    1.70                    }
    1.71 -                }
    1.72 -                if (WinRing0.Rdmsr(MSR_PLATFORM_INFO, out eax, out edx)) {
    1.73 -                  maxNehalemMultiplier = (eax >> 8) & 0xff;
    1.74 -                }
    1.75 +                }                
    1.76                  break;
    1.77                default:
    1.78 -                tjMax = Floats(100); break;
    1.79 +                microarchitecture = Microarchitecture.Unknown;
    1.80 +                tjMax = Floats(100); 
    1.81 +                break;
    1.82              }
    1.83            } break;
    1.84 -        default: tjMax = Floats(100); break;
    1.85 +        default:
    1.86 +          microarchitecture = Microarchitecture.Unknown;
    1.87 +          tjMax = Floats(100); 
    1.88 +          break;
    1.89 +      }
    1.90 +
    1.91 +      // set timeStampCounterMultiplier
    1.92 +      switch (microarchitecture) {
    1.93 +        case Microarchitecture.Atom:
    1.94 +        case Microarchitecture.Core: {
    1.95 +            uint eax, edx;
    1.96 +            if (WinRing0.Rdmsr(IA32_PERF_STATUS, out eax, out edx)) {
    1.97 +              timeStampCounterMultiplier = 
    1.98 +                ((edx >> 8) & 0x1f) + 0.5 * ((edx >> 14) & 1);
    1.99 +            }
   1.100 +          } break;
   1.101 +        case Microarchitecture.Nehalem: {
   1.102 +            uint eax, edx;
   1.103 +            if (WinRing0.Rdmsr(MSR_PLATFORM_INFO, out eax, out edx)) {
   1.104 +              timeStampCounterMultiplier = (eax >> 8) & 0xff;
   1.105 +            }
   1.106 +          } break;
   1.107 +        default:
   1.108 +          timeStampCounterMultiplier = 1;
   1.109 +          break;
   1.110        }
   1.111  
   1.112        // check if processor supports a digital thermal sensor
   1.113 @@ -161,6 +198,18 @@
   1.114        };
   1.115      }
   1.116  
   1.117 +    public override string GetReport() {
   1.118 +      StringBuilder r = new StringBuilder();
   1.119 +      r.Append(base.GetReport());
   1.120 +
   1.121 +      r.Append("Time Stamp Counter Multiplier: ");
   1.122 +      r.AppendLine(timeStampCounterMultiplier.ToString(
   1.123 +        CultureInfo.InvariantCulture));
   1.124 +      r.AppendLine();
   1.125 +
   1.126 +      return r.ToString();
   1.127 +    }
   1.128 +
   1.129      public override void Update() {
   1.130        base.Update();
   1.131  
   1.132 @@ -188,27 +237,18 @@
   1.133          for (int i = 0; i < coreClocks.Length; i++) {
   1.134            System.Threading.Thread.Sleep(1);
   1.135            if (WinRing0.RdmsrTx(IA32_PERF_STATUS, out eax, out edx,
   1.136 -            (UIntPtr)(1L << cpuid[i][0].Thread))) {
   1.137 -            if (maxNehalemMultiplier > 0) { // Core i3, i5, i7
   1.138 -              uint nehalemMultiplier = eax & 0xff;
   1.139 -              coreClocks[i].Value =(float)(nehalemMultiplier * 
   1.140 -                TimeStampCounterFrequency / maxNehalemMultiplier);
   1.141 -              newBusClock = 
   1.142 -                (float)(TimeStampCounterFrequency / maxNehalemMultiplier);
   1.143 -            } else { // Core 2
   1.144 -              uint multiplier = (eax >> 8) & 0x1f;
   1.145 -              uint maxMultiplier = (edx >> 8) & 0x1f;
   1.146 -              // factor = multiplier * 2 to handle non integer multipliers 
   1.147 -              uint factor = (multiplier << 1) | ((eax >> 14) & 1);
   1.148 -              uint maxFactor = (maxMultiplier << 1) | ((edx >> 14) & 1);
   1.149 -              if (maxFactor > 0) {
   1.150 -                coreClocks[i].Value = 
   1.151 -                  (float)(factor * TimeStampCounterFrequency / maxFactor);
   1.152 -                newBusClock = 
   1.153 -                  (float)(2 * TimeStampCounterFrequency / maxFactor);
   1.154 -              }
   1.155 -            }
   1.156 -          } else { // Intel Pentium 4
   1.157 +            (UIntPtr)(1L << cpuid[i][0].Thread))) 
   1.158 +          {
   1.159 +            newBusClock = 
   1.160 +              TimeStampCounterFrequency / timeStampCounterMultiplier;
   1.161 +            if (microarchitecture == Microarchitecture.Nehalem) {
   1.162 +              uint multiplier = eax & 0xff;
   1.163 +              coreClocks[i].Value = (float)(multiplier * newBusClock);
   1.164 +            } else {
   1.165 +              double multiplier = ((eax >> 8) & 0x1f) + 0.5 * ((eax >> 14) & 1);
   1.166 +              coreClocks[i].Value = (float)(multiplier * newBusClock);
   1.167 +            }            
   1.168 +          } else { 
   1.169              // if IA32_PERF_STATUS is not available, assume TSC frequency
   1.170              coreClocks[i].Value = (float)TimeStampCounterFrequency;
   1.171            }
     2.1 --- a/Properties/AssemblyVersion.cs	Fri Oct 08 12:18:32 2010 +0000
     2.2 +++ b/Properties/AssemblyVersion.cs	Sun Oct 10 16:57:11 2010 +0000
     2.3 @@ -37,5 +37,5 @@
     2.4  
     2.5  using System.Reflection;
     2.6  
     2.7 -[assembly: AssemblyVersion("0.2.1.0")]
     2.8 -[assembly: AssemblyInformationalVersion("0.2.1 Beta")]
     2.9 \ No newline at end of file
    2.10 +[assembly: AssemblyVersion("0.2.1.1")]
    2.11 +[assembly: AssemblyInformationalVersion("0.2.1.1 Alpha")]
    2.12 \ No newline at end of file