mirror of
https://github.com/openhardwaremonitor/openhardwaremonitor
synced 2025-09-01 14:55:13 +00:00
Improved the invariant TSC frequency estimation code to ignore readings with a large error.
This commit is contained in:
@@ -121,19 +121,9 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
|
|
||||||
if (hasTimeStampCounter) {
|
if (hasTimeStampCounter) {
|
||||||
estimatedTimeStampCounterFrequency =
|
estimatedTimeStampCounterFrequency =
|
||||||
EstimateTimeStampCounterFrequency();
|
EstimateTimeStampCounterFrequency();
|
||||||
|
|
||||||
// set initial values
|
|
||||||
uint lsb, msb;
|
|
||||||
WinRing0.RdtscTx(out lsb, out msb, (UIntPtr)1);
|
|
||||||
lastTime = Stopwatch.GetTimestamp();
|
|
||||||
lastTimeStampCount = ((ulong)msb << 32) | lsb;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
estimatedTimeStampCounterFrequency = 0;
|
estimatedTimeStampCounterFrequency = 0;
|
||||||
|
|
||||||
lastTime = 0;
|
|
||||||
lastTimeStampCount = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
timeStampCounterFrequency = estimatedTimeStampCounterFrequency;
|
timeStampCounterFrequency = estimatedTimeStampCounterFrequency;
|
||||||
@@ -259,18 +249,29 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override void Update() {
|
public override void Update() {
|
||||||
if (hasTimeStampCounter) {
|
if (hasTimeStampCounter && isInvariantTimeStampCounter) {
|
||||||
uint lsb, msb;
|
uint lsb, msb;
|
||||||
|
|
||||||
|
// read time before and after getting the TSC to estimate the error
|
||||||
|
long firstTime = Stopwatch.GetTimestamp();
|
||||||
WinRing0.RdtscTx(out lsb, out msb, (UIntPtr)1);
|
WinRing0.RdtscTx(out lsb, out msb, (UIntPtr)1);
|
||||||
long time = Stopwatch.GetTimestamp();
|
long time = Stopwatch.GetTimestamp();
|
||||||
|
|
||||||
ulong timeStampCount = ((ulong)msb << 32) | lsb;
|
ulong timeStampCount = ((ulong)msb << 32) | lsb;
|
||||||
double delta = ((double)(time - lastTime)) / Stopwatch.Frequency;
|
double delta = ((double)(time - lastTime)) / Stopwatch.Frequency;
|
||||||
if (delta > 0.5) {
|
double error = ((double)(time - firstTime)) / Stopwatch.Frequency;
|
||||||
if (isInvariantTimeStampCounter)
|
|
||||||
timeStampCounterFrequency =
|
// 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) {
|
||||||
|
|
||||||
|
// update the TSC frequency with the new value
|
||||||
|
timeStampCounterFrequency =
|
||||||
(timeStampCount - lastTimeStampCount) / (1e6 * delta);
|
(timeStampCount - lastTimeStampCount) / (1e6 * delta);
|
||||||
else
|
}
|
||||||
timeStampCounterFrequency = estimatedTimeStampCounterFrequency;
|
|
||||||
|
|
||||||
lastTimeStampCount = timeStampCount;
|
lastTimeStampCount = timeStampCount;
|
||||||
lastTime = time;
|
lastTime = time;
|
||||||
|
Reference in New Issue
Block a user