internal Cpu(int processorIndex, Cpuid[][] cpuid) : base(cpuid[0][0].Name) { Cpuid = cpuid; Vendor = cpuid[0][0].Vendor; Family = cpuid[0][0].Family; Model = cpuid[0][0].Model; Stepping = cpuid[0][0].Stepping; ProcessorIndex = processorIndex; CoreCount = cpuid.Length; // check if processor has MSRs HasModelSpecificRegisters = cpuid[0][0].Data.GetLength(0) > 1 && (cpuid[0][0].Data[1, 3] & 0x20) != 0; // check if processor has a TSC HasTimeStampCounter = cpuid[0][0].Data.GetLength(0) > 1 && (cpuid[0][0].Data[1, 3] & 0x10) != 0; // check if processor supports an invariant TSC _isInvariantTimeStampCounter = cpuid[0][0].ExtData.GetLength(0) > 7 && (cpuid[0][0].ExtData[7, 3] & 0x100) != 0; TotalLoad = CoreCount > 1 ? new Sensor("CPU Total", SensorType.Load) : null; CoreLoads = new Sensor[CoreCount]; for (var i = 0; i < CoreLoads.Length; i++) { CoreLoads[i] = new Sensor(CoreString(i), SensorType.Load); } _cpuLoad = new CpuLoad(cpuid); if (HasTimeStampCounter) { var mask = ThreadAffinity.Set(1UL << cpuid[0][0].Thread); EstimateTimeStampCounterFrequency( out _estimatedTimeStampCounterFrequency, out _estimatedTimeStampCounterFrequencyError); ThreadAffinity.Set(mask); } else { _estimatedTimeStampCounterFrequency = 0; } TimeStampCounterFrequency = _estimatedTimeStampCounterFrequency; }
protected Cpu(int processorIndex, CpuId[][] cpuId) : base(cpuId[0][0].Name) { this.CpuId = cpuId; Vendor = cpuId[0][0].Vendor; Identifier = $"{Vendor.ToString()}/{processorIndex.ToString()}"; family = cpuId[0][0].Family; model = cpuId[0][0].Model; stepping = cpuId[0][0].Stepping; this.processorIndex = processorIndex; CoreCount = cpuId.Length; // check if processor has MSRs if (cpuId[0][0].Data.GetLength(0) > 1 && (cpuId[0][0].Data[1, 3] & 0x20) != 0) { HasModelSpecificRegisters = true; } else { HasModelSpecificRegisters = false; } // check if processor has a TSC if (cpuId[0][0].Data.GetLength(0) > 1 && (cpuId[0][0].Data[1, 3] & 0x10) != 0) { HasTimeStampCounter = true; } else { HasTimeStampCounter = false; } // check if processor supports an invariant TSC if (cpuId[0][0].ExtData.GetLength(0) > 7 && (cpuId[0][0].ExtData[7, 3] & 0x100) != 0) { isInvariantTimeStampCounter = true; } else { isInvariantTimeStampCounter = false; } TotalLoad = CoreCount > 1 ? new Sensor("CPU Total", 0, SensorType.Load, this) : null; CoreLoads = new Sensor[CoreCount]; for (var i = 0; i < CoreLoads.Length; i++) { CoreLoads[i] = new Sensor(CoreString(i), i + 1, SensorType.Load, this); } CpuLoad = new CpuLoad(cpuId); if (CpuLoad.IsAvailable) { foreach (var sensor in CoreLoads) { ActivateSensor(sensor); } if (TotalLoad != null) { ActivateSensor(TotalLoad); } } if (HasTimeStampCounter) { var mask = ThreadAffinity.Set(1UL << cpuId[0][0].Thread); EstimateTimeStampCounterFrequency(); ThreadAffinity.Set(mask); } else { EstimatedTimeStampCounterFrequency = 0; } TimeStampCounterFrequency = EstimatedTimeStampCounterFrequency; }
public override void Update() { if (CoreClocks.Any(x => x == null)) { CoreClocks = CoreClocks.Where(x => x != null).ToArray(); } if (CoreLoads.Any(x => x == null)) { CoreLoads = CoreLoads.Where(x => x != null).ToArray(); } if (CorePowers.Any(x => x == null)) { CorePowers = CorePowers.Where(x => x != null).ToArray(); } if (CoreTemperatures.Any(x => x == null)) { CoreTemperatures = CoreTemperatures.Where(x => x != null).ToArray(); } if (CoreVoltages.Any(x => x == null)) { CoreVoltages = CoreVoltages.Where(x => x != null).ToArray(); } if (HasTimeStampCounter && isInvariantTimeStampCounter) { // make sure always the same thread is used var mask = ThreadAffinity.Set(1UL << CpuId[0][0].Thread); // read time before and after getting the TSC to estimate the error var firstTime = Stopwatch.GetTimestamp(); var timeStampCount = Opcode.Rdtsc(); var time = Stopwatch.GetTimestamp(); // restore the thread affinity mask ThreadAffinity.Set(mask); var delta = (double)(time - lastTime) / Stopwatch.Frequency; var error = (double)(time - firstTime) / Stopwatch.Frequency; // only use data if they are measured accuarte enough (max 0.1ms delay) if (error < 0.0001) { // ignore the first reading because there are no initial values // ignore readings with too large or too small time window if (lastTime != 0 && delta > 0.5 && delta < 2) { TimeStampCounterFrequency = (timeStampCount - lastTimeStampCount) / (1e6 * delta); } lastTimeStampCount = timeStampCount; lastTime = time; } } if (CpuLoad.IsAvailable) { CpuLoad.Update(); for (var i = 0; i < CoreLoads.Length; i++) { CoreLoads[i].Value = CpuLoad.GetCoreLoad(i); } if (TotalLoad != null) { TotalLoad.Value = CpuLoad.GetTotalLoad(); } } }