Skip to main content
GameDev.net gamedev.net
🔒 Locked

C# High Resolution Timer

Started by GroZZleR Jan 6, 2005 at 12:48 PM 10 replies 5.8k views
Original Post
GroZZleR
GroZZleR
Sorry if this has been asked before but the search feature is down. Are there any built-in high resolution timers for C# or is importing QueryPerformanceCounter (and related functions) the way to go?
leedgitar
leedgitar
QPC is the way to go for now.


Note: The 2.0 class is System.Diagnostics.Stopwatch

http://longhorn.msdn.microsoft.com/?//longhorn.msdn.microsoft.com/lhsdk/ref/ns/System.Diagnostics/c/Stopwatch/Stopwatch.aspx
________________________________________________Chris McGuirkLead Programmer - Axiom 3D EngineC# gaming, the way of the future!http://www.axiom3d.org
nife
nife
There's one built into your CPU!
The Read Time Stamp Counter (RDTSC) Assembly instruction will increment every clock cycle...
Killers don't end up in jailThey end up on a high-score!
hplus0603
hplus0603
@nife: Do you know some secret way of including inline assembly in a C# program that you're not telling us about?

The only way I know is to build it in unsafe C++ and importing it, which is a pretty annoying development path -- not to mention your entire assembly is then unsafe.
enum Bool { True, False, FileNotFound };
nife
nife
Can't you just link an obj file already compiled with NASM or MASM?

Who cares if a couple of instructions is unsafe (well, I guess you do ;-))? Just calling the RDTSC and returning in EAX shouldn't be a risk in my opinion...
Killers don't end up in jailThey end up on a high-score!
nimrand
nimrand
Quote:
Original post by nife
Can't you just link an obj file already compiled with NASM or MASM?

Who cares if a couple of instructions is unsafe (well, I guess you do ;-))? Just calling the RDTSC and returning in EAX shouldn't be a risk in my opinion...


I'm afraid you've missed the point. In .NET land, there are two kinds of assemblies. Safe assemblies and unsafe assemblies. Even though your assembly instructions are entirely harmless in this case, the .NET Runtime can't distinguish between it and malicious or buggy code that could do harmfull things. Therefore, it will require the end users to increase the program's security permissions just so the program can check the time.

EDIT: Corrected typo.
GroZZleR
GroZZleR
Wait... If I import QPC and related functions from a DLL my program is considered unsafe?

And Mykre, I can't seem to find it. Any idea what the sample is called?
Synex
Synex
Here is what i use:

using System;using System.Runtime.InteropServices;using System.ComponentModel;using System.Threading;namespace SysUtil{	/// <summary>	/// Summary description for HiPerfTimer.	/// </summary>	public class HiPerfTimer	{		[DllImport("Kernel32.dll")]		private static extern bool QueryPerformanceCounter(			out long lpPerformanceCount);		[DllImport("Kernel32.dll")]		private static extern bool QueryPerformanceFrequency(			out long lpFrequency);		private long startTime, stopTime;		private long freq;		public HiPerfTimer()		{			startTime = 0;			stopTime  = 0;			if (QueryPerformanceFrequency(out freq) == false)			{				// high-performance counter not supported				throw new Win32Exception();			}		}		// Start the timer		public void Start()		{			// lets do the waiting threads there work			Thread.Sleep(0);			QueryPerformanceCounter(out startTime);		}		// Stop the timer		public void Stop()		{			QueryPerformanceCounter(out stopTime);		}		public long GetFreq()		{			return freq;		}		public long Query()		{			long time;			QueryPerformanceCounter(out time);			return time;		}		// Returns the duration of the timer (in seconds)		public double Duration		{			get			{				return (double)(stopTime - startTime) / (double) freq;			}		}	}}

SynexCode Monkey
Slug
Slug
//That my own timer class witch is easyer to use that anything

//The header file
#ifndef CTIMER_H
#define CTIMER_H

#include
#include

class CTimer
{
private:
bool m_PerfCounterAvailable;
float m_TimeScale;
__int64 m_LastTime; //--Holds the value when the timer is started
__int64 m_CurrentTime; //--Holds the current time
__int64 m_PerfCounterFreq; // Performance Frequency


public:
CTimer();
//virtual ~CTimer();

void Tick(); //--Count how many time has pass since the last call of Tick();
float g_ElapsedTime; //--Holds the elapsed time (StartTime - CurrentTime)

};

#endif //--CTIMER_H

//The cpp file
#include "Timer.h"

CTimer::CTimer()
{
if (QueryPerformanceFrequency((LARGE_INTEGER *)&m_PerfCounterFrequency))
{
m_PerfCounterAvailable = true;
QueryPerformanceCounter((LARGE_INTEGER *) &m_CurrentTime);
m_TimeScale = 1.0f / m_PerfCounterFrequency;
}
else
{
// no performance counter, read in using timeGetTime
m_PerfCounterAvailable = false;
m_CurrentTime = timeGetTime();
m_TimeScale = 0.001f;

} // End If No Hardware

m_LastTime = m_CurrentTime;
g_ElapsedTime = 0.0f;
}


void CTimer::Tick()
{
m_LastTime = m_CurrentTime;

// Is performance hardware available?
if(m_PerfCounterAvailable){
// Query high-resolution performance hardware
QueryPerformanceCounter((LARGE_INTEGER *)&m_CurrentTime);
} else {
// Fall back to less accurate timer
m_CurrentTime = timeGetTime();

} // End If no hardware available

g_ElapsedTime = (m_CurrentTime - m_LastTime) * m_TimeScale;
}

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.