CSCI 4717 -- High Performance Counter


High Resolution Counter

Let's play around with the high resolution counter again. Remember that this counter counts the number of clock cycles of the system clock since the system was last powered up. The function we use to read this timer is QueryPerformanceCounter(). Since function reads the processor's high resolution timer which is incremented once with every clock pulse of the processor's clock, then for a 3.59 GHz machine, this timer is incremented approximately 3,590,000,000 times in a second. QueryPerformanceCounter() takes as its single parameter a pointer to a LARGE_INTEGER which you define in your code. This gives us a way to read how many clock cycles have occurred since the machine was turned on.

LARGE_INTEGER current_time;
QueryPerformanceCounter(&current_time);

The number returned by QueryPerformanceCounter() is huge and not very useful for timing at the "seconds" level. As I mentioned earlier, it is incremented once with every pulse of the system clock. If we knew the system clock frequency, we could figure out how many seconds had passed since turning on the machine. This can be done with QueryPerformanceFrequency(). This function returns the frequency of the processor once again using a LARGE_INTEGER passed as a pointer for the function's only parameter.

LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);

Dividing the counter value by the frequency will convert the time to seconds. Dividing the counter value by the frequency divided by 1,000 will convert the time to milliseconds. Dividing the counter value by the frequency divided by 1,000,000 will convert the time to microseconds and so on.

Laboratory Exercise

In today's exercise, we will be using the counter to measure time. For the most part, we will be measuring time in microseconds. Begin by creating a console application in Visual Studio 2005. Below is some sample code that should work well for a template as we go through some of these examples. Remember that LARGE_INTEGER is a UNION, so to access the value stored in it, you must define the way you want the data returned. To do this, use the QuadPart component.

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include "Windows.h"

using namespace std;

int main( )
{
    LARGE_INTEGER current, frequency;
    QueryPerformanceFrequency(&frequency);
    QueryPerformanceCounter(&current);
    cout << current.QuadPart/(frequency.QuadPart/1000000) << " uS have passed since resetting the high performance counter.\n";
    return 0;
}

Today, we will see if we can get some semi-accurate measurements of the following programming functions.