Up

A Problem in Measuring Time by vsgGetTimer( )/ViSaGe

An alternative timer with finer resolution

 

Function vsgGetTimer( ) returns a value with 100microsecond precision. But, when the program runs on a multi-task OS like Windows, switching between tasks may bring a trouble.  To check this possibility, I wrote the following console application in Visual C++ 2008/CLR.

=====================================================

#include "stdafx.h"

#include <VSGV8.H>

 

using namespace System;

 

int main(array<System::String ^> ^args)

{

        ::vsgInit("");

        ::vsgResetTimer();

        const int N = 100;

        int x[N];

        int cnt = 0;

        int t0, t1, ckt0, ckt1;

        ckt0 = t0 = ::vsgGetTimer();

        do {

                t1 = ::vsgGetTimer();

                if (t1 > t0){

                        x[cnt++] = t1 - t0;

                        t0 = t1;

                }

        } while (cnt < N);

        ckt1 = t1;

        for (int i = 0; i < N; i++){

                Console::Write(((x[i]*0.001).ToString() + "ms")->PadLeft(10));

                if (i % 5 == 4) Console::WriteLine();

        }

        Console::WriteLine();

        Console::WriteLine("Mean interval between increments = " + ((ckt1 - ckt0) * 0.001 / double(N)).ToString() + "ms");

 

        Console::WriteLine();

        Console::WriteLine("Press the Enter key.");

        Console::ReadLine();

    return 0;

}

========================================================

 

Run this code on ViSaGe, then you will get the following result (Figure 1).

CheckClockTimer.bmp

Figure 1

 

Figure 1 shows that multi-tasking may introduce an error up to 15.625ms in measuring time.

 

 

I prepared a timer class with finer resolution than vsgGetTimer.  This class is coded as follows:

==================== Header file finetimer.h =====================================

//

//              A fine resolution timer.  Y. Okamoto,  2010.03

//

#ifndef FINETIMER_CK

#define FINETIMER_CK

 

#include <Windows.h>

 

using namespace System;

 

namespace mytimer {

 

        class MyTimer {

                public:

 

                        LARGE_INTEGER L_I;

                        bool ck;

                        double f;

                        double c;

 

                        MyTimer(): ck(false) {

                                if ( QueryPerformanceFrequency( &L_I ) ) {

                                        ck = true;

                                        c = Math::Pow(2.0, 32.0);

                                        f = L_I.LowPart + c * L_I.HighPart;

                                }

                        }

 

                        //      In microsecond unit

                        double time(){

                                if (ck) {

                                        QueryPerformanceCounter( &L_I );

                                        double v = L_I.HighPart * c + L_I.LowPart;

                                        return 1000000.0 * v / f;

                                } else {

                                        return 0.0;

                                }

                        }

 

                        //      In millisecond unit

                        int timems(){

                                return Math::Round(time() * 0.001);

                        }

 

        };

 

}

 

#endif

===========================  End of header file finetimer.h  ===============================================

 

You can check finetimer.h by the following console application in Visual C++2008/CLR

 

=======================   A main source file finertimer.cpp to check finetimer.h  ===============================

#include "stdafx.h"

 

#include "finetimer.h"

 

using namespace System;

using namespace mytimer;

 

int main(array<System::String ^> ^args)

{

        const int N = 100;

        int x[N];

        int cnt = 0;

        int t0, t1, ckt0, ckt1;

        MyTimer mt;

        ckt0 = t0 = mt.timems();

        do {

                t1 = mt.timems();

                if (t1 > t0){

                        x[cnt++] = t1 - t0;

                        t0 = t1;

                }

        } while (cnt < N);

        ckt1 = t1;

        for (int i = 0; i < N; i++){

                Console::Write((x[i].ToString() + "ms")->PadLeft(10));

                if (i % 5 == 4) Console::WriteLine();

        }

        Console::WriteLine();

        Console::WriteLine("Mean interval between increments = " + ((ckt1 - ckt0) / double(N)).ToString() + "ms");

 

        Console::WriteLine();

        Console::WriteLine("Press the Enter key.");

        Console::ReadLine();

    return 0;

=============================   End of finertimer.cpp  ======================================================

 

Run the program finertimer.cpp, you will get the following result.

 

============================================================

       1ms       1ms       1ms       1ms       1ms

       1ms       1ms       1ms       1ms       1ms

       1ms       1ms       1ms       1ms       1ms

       1ms       1ms       1ms       1ms       1ms

       1ms       1ms       1ms       1ms       1ms

       1ms       1ms       1ms       1ms       1ms

       1ms       1ms       1ms       1ms       1ms

       1ms       1ms       1ms       1ms       1ms

       1ms       1ms       1ms       1ms       1ms

       1ms       1ms       1ms       1ms       1ms

       1ms       1ms       1ms       1ms       1ms

       1ms       1ms       1ms       1ms       1ms

       1ms       1ms       1ms       1ms       1ms

       1ms       1ms       1ms       1ms       1ms

       1ms       1ms       1ms       1ms       1ms

       1ms       1ms       1ms       1ms       1ms

       1ms       1ms       1ms       1ms       1ms

       1ms       1ms       1ms       1ms       1ms

       1ms       1ms       1ms       1ms       1ms

       1ms       1ms       1ms       1ms       1ms

 

Mean interval between increments = 1ms

 

Press the Enter key.

===========================================================

 

Release version of the above program (.NET Framework 3.5) finertimer.exe

Packed files (Visual C++ 2008) finertimer.zip

 

More information about QueryPerformanceCounter function in Japanesec

 

Up