Improved the invariant TSC frequency estimation code to ignore readings with a large error.
1.1 --- a/Hardware/CPU/GenericCPU.cs Thu Oct 14 16:52:23 2010 +0000
1.2 +++ b/Hardware/CPU/GenericCPU.cs Thu Oct 14 17:30:51 2010 +0000
1.3 @@ -121,19 +121,9 @@
1.4
1.5 if (hasTimeStampCounter) {
1.6 estimatedTimeStampCounterFrequency =
1.7 - EstimateTimeStampCounterFrequency();
1.8 -
1.9 - // set initial values
1.10 - uint lsb, msb;
1.11 - WinRing0.RdtscTx(out lsb, out msb, (UIntPtr)1);
1.12 - lastTime = Stopwatch.GetTimestamp();
1.13 - lastTimeStampCount = ((ulong)msb << 32) | lsb;
1.14 -
1.15 + EstimateTimeStampCounterFrequency();
1.16 } else {
1.17 estimatedTimeStampCounterFrequency = 0;
1.18 -
1.19 - lastTime = 0;
1.20 - lastTimeStampCount = 0;
1.21 }
1.22
1.23 timeStampCounterFrequency = estimatedTimeStampCounterFrequency;
1.24 @@ -259,18 +249,29 @@
1.25 }
1.26
1.27 public override void Update() {
1.28 - if (hasTimeStampCounter) {
1.29 + if (hasTimeStampCounter && isInvariantTimeStampCounter) {
1.30 uint lsb, msb;
1.31 +
1.32 + // read time before and after getting the TSC to estimate the error
1.33 + long firstTime = Stopwatch.GetTimestamp();
1.34 WinRing0.RdtscTx(out lsb, out msb, (UIntPtr)1);
1.35 long time = Stopwatch.GetTimestamp();
1.36 +
1.37 ulong timeStampCount = ((ulong)msb << 32) | lsb;
1.38 double delta = ((double)(time - lastTime)) / Stopwatch.Frequency;
1.39 - if (delta > 0.5) {
1.40 - if (isInvariantTimeStampCounter)
1.41 - timeStampCounterFrequency =
1.42 + double error = ((double)(time - firstTime)) / Stopwatch.Frequency;
1.43 +
1.44 + // only use data if they are measured accuarte enough (max 0.1ms delay)
1.45 + if (error < 0.0001) {
1.46 +
1.47 + // ignore the first reading because there are no initial values
1.48 + // ignore readings with too large or too small time window
1.49 + if (lastTime != 0 && delta > 0.5 && delta < 2) {
1.50 +
1.51 + // update the TSC frequency with the new value
1.52 + timeStampCounterFrequency =
1.53 (timeStampCount - lastTimeStampCount) / (1e6 * delta);
1.54 - else
1.55 - timeStampCounterFrequency = estimatedTimeStampCounterFrequency;
1.56 + }
1.57
1.58 lastTimeStampCount = timeStampCount;
1.59 lastTime = time;