Question

I am trying to write a class that will be able to time events using QueryPerformanceCounter in C++. The idea is that you create a timer object, give a function a time in double format, and it counts until that time has passed by and does stuff afterwards. This class will ideally be used for timing things in a game ( having a timer that counts 60 times in a second for example). When i compile this code though, it just prints 0's to the console, seemingly for ever. But i noticed some kind of bug that i can't understand. If i click on the scroll bar of the console window and hold it, the timer actually counts properly. If i enter 5.0 for example, then quickly click and hold the scroll bar for 5 seconds or longer, when i let go the program will print 'Done!!!'. so why doesn't it count properly when i just let it print the elapsed time to the console? is there a glitch with printing things to the console, or is there something wrong with my timing code? Below is the code:

   #include <iostream>
#include <iomanip>
#include "windows.h"

using namespace std;



int main()
{

    setprecision(10); // i tried to see if precision in the stream was the problem but i don't think it is

    cout << "hello! lets time something..." << endl;

    bool timing = 0;                // a switch to turn the timer on and off
    LARGE_INTEGER T1, T2;           // the timestamps to count
    LARGE_INTEGER freq;             // the frequency per seccond for measuring the difference between the stamp values

    QueryPerformanceFrequency(&freq); // gets the frequency from the computer

    // mil.QuadPart = freq.QuadPart / 1000; // not used


    double ellapsedtime = 0, desiredtime; // enter a value to count up to in secconds
    // if you entered 4.5 for example, then it should wait for 4.5 secconds

    cout << "enter the amount of time you would like to wait for in seconds (in double format.)!!" << endl;
    cin >> desiredtime;

    QueryPerformanceCounter(&T1);   // gets the first stamp value
    timing = 1;                    // switches the timer on

    while(timing)
    {
        QueryPerformanceCounter(&T2);      // gets another stamp value
        ellapsedtime += (T2.QuadPart - T1.QuadPart) / freq.QuadPart;   // measures the difference between the two stamp
        //values and then divides them by the frequency to get how many secconds has ellapsed
        cout << ellapsedtime << endl;
        T1.QuadPart = T2.QuadPart; // assigns the value of the second stamp to the first one, so that we can measure the
        // difference between them again and again

        if(ellapsedtime>=desiredtime) // checks if the elapsed time is bigger than or equal to the desired time,
        // and if it is prints done and turns the timer off
        {
            cout << "done!!!" << endl;
            timing = 0; // breaks the loop
        }
    }



    return 0;
}
Was it helpful?

Solution

You should store in ellapsedtime the number of microseconds elapsed since the fisrt call to QueryPerformanceCounter, and you should not overwrite the first time stamp.

Working code:

// gets another stamp value
QueryPerformanceCounter(&T2);     

// measures the difference between the two stamp
ellapsedtime += (T2.QuadPart - T1.QuadPart);

cout << "number of tick " << ellapsedtime << endl;
ellapsedtime *= 1000000.;
ellapsedtime /= freq.QuadPart;
cout << "number of Microseconds " << ellapsedtime << endl;

// checks if the elapsed time is bigger than or equal to the desired time
if(ellapsedtime/1000000.>=desiredtime)         {
   cout << "done!!!" << endl;
   timing = 0; // breaks the loop
}

Be sure to read : Acquiring high-resolution time stamps

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top