..
#gamedev

Time Elapsed in Game With Query Performance

To find out the time spent in the program first let's find how many ticks occurred in a frame.

Before the main loop and end of main loop we define the QueryPerformanceCounter.

// before main loop
LARGE_INTEGER lastCounter;
QueryPerformanceCounter(&lastCounter);


// while { ...
    // end of main loop
    LARGE_INTEGER endCounter;
    QueryPerformanceCounter(&endCounter);
// }

int64 counterElapsed = endCounter.QuadPart - lastCounter.QuadPart;

Now, knowing how many ticks occurred within a frame, we need to know what the CPU frequency is in seconds, I mean, how many ticks the CPU can make within one second.

This way we will find out how much time has passed in an MSPERFRAME - milliseconds per frame.

The value that the CPU can count is a value that can be cached (read global) at the beginning of the program right after the main function. Example of captured value: (10000000).

void main() {
    // in seconds
    LARGE_INTEGER frequency;
    QueryPerformanceFrequency(&frequency);
    int64 perfFrequency = frequency.QuadPart;
}

Now, we can divide the frequency by the number of ticks to find its value (in seconds).

However, let's first transform it into milliseconds so that the number is not truncated because it is too large.

/*
  count     count      count     sec       sec
  =====  *  =====   =  =====  / =====   = =====
    1        sec         1       count      1
*/
double secondsPerFrame = (1000.0 * (double) counterElapsed) / (double) perfFrequency;

Now, let's compute how many mega cycles the CPU makes in each frame. It is similar to calculating milliseconds per frame.

At the start of the program:

uint64 endCPU = __rdtsc();

__rdtsc() is a function intrinsic processor access and will return the processor time stamp - read timestamp counter.

uint64 endCPU = __rdtsc();
uint64 cyclesElapsed  = endCPU - lastCPU;

Now let's find out the value of mega cycles per frame.

int32 mcpf = (int32) cyclesElapsed / (1000 * 1000); // convert to mega

Calculating frames per seconds - FPS:

int32 fps = 1.0 / secondsPerFrame;

By inverting the operator for division, we can find the frames per second from the seconds per frame.

By multiplying mcpf * fps we find the value that our processor is currently working on.

For printing formatted values, let's use a buffer with wsprintf:

char buffer[256];
// MC * FPS = processor speed

wsprintf(buffer, "ms/f: %d, fps: %d, MC/f: %d\n", 1000.0 * secondsPerFrame, fps, mcpf);

OutputDebugStringA(buffer);