A High-Resolution Timer for Win32

This post lists the code for creating a high resolution timer for the Microsoft Windows platform. High resolution timers are often used in multimedia and entertainment applications for timing events up to the microsecond.

This is a heavily modified re-post of the article that used to be on the Scriptionary.com website before the change to the blog, read the source code for details.

#ifndef _TIMER_H_
#define _TIMER_H_

#ifndef WIN32_LEAN_AND_MEAN
#	define WIN32_LEAN_AND_MEAN
#endif

#include <windows.h>

// Defines a simple High Resolution Timer
class Timer
{
public:
	// Construct the timer and initialize all of the
	// members by resetting them to their zero-values.
	Timer(void) {
		Reset();
	}

	~Timer(void){ /* empty */ }

	// Activate the timer and poll the counter.
	void Start(void) {
		_Active = true;
		PollCounter(_StartCount);
	}

	// Deactivate the timer and poll the counter.
	void Stop(void) {
		_Active = false;
		PollCounter(_EndCount);
	}

	// Stops the timer if it's active and resets all
	// of the Timer's members to their initial values.
	void Reset(void) {
		if (_Active)
			Stop();

		QueryPerformanceFrequency(&_Frequency);

		_StartTime = (_EndTime = 0.0);
		_StartCount.QuadPart = (_EndCount.QuadPart = 0);
		_Active = false;
	}

	// Returns the time elapsed since Start() was called
	// in micro-seconds
	const long double GetTimeInMicroSeconds(void) {
		const long double MicroFreq =
			1000000.0 / _Frequency.QuadPart;

		if (_Active)
			PollCounter(_EndCount);

		_StartTime = _StartCount.QuadPart * MicroFreq;
		_EndTime = _EndCount.QuadPart * MicroFreq;

		return _EndTime - _StartTime;
	}

	// Returns the time elapsed since Start() was called
	// in milli-seconds
	const long double GetTimeInMilliseconds(void) {
		return GetTimeInMicroSeconds() * 0.001;
	}

	// Returns the time elapsed since Start() was called
	// in seconds
	const long double GetTimeInSeconds( void ) {
		return GetTimeInMicroSeconds() * 0.000001;
	}

	// Returns TRUE if the Timer is currently active
	const bool IsActive(void) const {
		return _Active;
	}
private:
	// Poll the query performance counter, safely by tying
	// the polling functionality temporarily to a single
	// logical processor (identified by 0).
	void PollCounter(LARGE_INTEGER& Out) {
		HANDLE Thread = GetCurrentThread();

		DWORD_PTR OldMask = SetThreadAffinityMask(Thread, 0);
			QueryPerformanceCounter(&Out);
		SetThreadAffinityMask(Thread, OldMask);
	}

private:
	bool _Active;
	long double
		_StartTime,
		_EndTime;
	LARGE_INTEGER
		_Frequency,
		_StartCount,
		_EndCount;
}; // class Timer

#endif

Here’s an incredibly simple example of how you could potentially use the class:

int main( int argc, const char* argv[] )
{
	Timer myTime;

	std::cout << "Starting the Timer..." << std::endl;
	MyTime.Start();

	std::cout << "Going to sleep for 5 seconds." << std::endl;
	Sleep(5000); // or something else for a while

	std::cout << "Stopping the Timer." << std::endl;
	MyTime.Stop();

	std::cout << MyTime.GetTimeInSeconds()
		<< " seconds passed" << std::endl;

	return 0;
}

Leave a Comment