Beispiel #1
0
        // Returns the ratio of a TPM clock second to one system time second
        public static double MeasureClockRate(Tpm2 tpm)
        {
            const int MaxIter           = 20;
            int       NumSamplesPerIter = 5;
            int       N = NumSamplesPerIter,
                      L = 0;

            double[] tpmTimes    = null;
            double[] sysTimes    = null;
            double[] newTpmTimes = new double[N];
            double[] newSysTimes = new double[N];
            int      iter        = 0;

            double stdDevSys = 0,
                   meanSys = 0,
                   stdDevTpm = 0,
                   meanTpm = 0;
            int    n = 0;
            double sysTime = 0, tpmTime = 0;

            do
            {
                tpmTimes = newTpmTimes;
                sysTimes = newSysTimes;

                TimeInfo tpmStart = null;
                DateTime sysStart = DateTime.MinValue;

                for (int i = L; i <= N; i++)
                {
                    TimeInfo tpmStop = tpm.ReadClock();
                    DateTime sysStop = DateTime.Now;
                    if (tpmStart != null)
                    {
                        tpmTimes[i - 1] = tpmStop.time - tpmStart.time;
                        sysTimes[i - 1] = (sysStop - sysStart).TotalMilliseconds;
                    }
                    tpmStart = tpmStop;
                    sysStart = sysStop;
                    Thread.Sleep(600);
                }

                // Eliminate outliers that may be caused by the current thread having
                // been preempted at a "wrong" point causing the measured rate distortion.
                meanSys = meanTpm = stdDevSys = stdDevTpm = sysTime = tpmTime = 0;
                for (int i = 0; i < N; i++)
                {
                    meanSys += sysTimes[i];
                    meanTpm += tpmTimes[i];
                }
                meanSys /= N;
                meanTpm /= N;

                for (int i = 0; i < N; i++)
                {
                    double d = (sysTimes[i] - meanSys);
                    stdDevSys += d * d;
                    d          = (tpmTimes[i] - meanTpm);
                    stdDevTpm += d * d;
                }
                stdDevSys = Math.Sqrt(stdDevSys / N);
                stdDevTpm = Math.Sqrt(stdDevTpm / N);

                bool imprecise = stdDevSys / meanSys > 0.03 || stdDevTpm / meanTpm > 0.03;
                if (imprecise)
                {
                    newTpmTimes = new double[N + NumSamplesPerIter];
                    newSysTimes = new double[N + NumSamplesPerIter];
                }

                n = 0;
                for (int i = 0; i < N; i++)
                {
                    if (Math.Abs(sysTimes[i] - meanSys) < 2 * stdDevSys &&
                        Math.Abs(tpmTimes[i] - meanTpm) < 2 * stdDevTpm)
                    {
                        sysTime += sysTimes[i];
                        tpmTime += tpmTimes[i];
                        if (imprecise)
                        {
                            newSysTimes[n] = sysTimes[i];
                            newTpmTimes[n] = tpmTimes[i];
                        }
                        ++n;
                    }
                    //else Console.Write("Dropped[{0}] = {1} ", i, sysTimes[i]);
                }
                if (!imprecise && n > 2)
                {
                    break;
                }
                L = n;
                N = L + NumSamplesPerIter;
            } while (++iter < MaxIter);

            if (iter == MaxIter)
            {
                Globs.Throw("The system is likely overloaded. Cannot do reliable time measurements.");
            }

            //Console.WriteLine("ITER {0}, MEAN {1:F0}->{2:F0}, SD {3:F1}; Good {4}; RATE {5:F2}",
            //                  iter+1, meanSys, sysTime / n, stdDevSys, n, tpmTime / sysTime);
            return(tpmTime / sysTime);
        } // MeasureClockRate()