Sign in to follow this  
Grain

High Precision Timers

Recommended Posts

How can I get a high precision timer, (like with microsecond resolution or better) in a platform independent way? I found some examples using goggle that use RDTSC but were very windows specific, like this one CCPUTicker If some one can talk me through creating one or point me in the direction of one that exists it would be greatly appreciated.

Share this post


Link to post
Share on other sites
RDTSC is a processor instruction so it's certainly not Windows specific. However it might be Pentium specific - I wouldn't want to say it is supported by AMD without knowing for sure.

If it is though - that will give you a very high resolution time, accurate to more than a microsecond.

Share this post


Link to post
Share on other sites
Sorry to dissapoint you, but there is no platform independant solution for high-precision timers. The only method that works across all modern x86 platforms is the RDTSC instruction. You would, however, have to implement the call in a compiler-specific way (e.g. there are different inline-assembly syntaxes).
Your second option is to research API-specific solutions for each platform you want to support and create platform/API-specific implementations for them along with a uniform public interface.

Regards,
Pat

Share this post


Link to post
Share on other sites
AMD supports rdtsc, I'm pretty sure it was added with Pentiums (and may have been undocumented on the 486).

rdtsc has issues on platforms where the clock can change on-the-fly, such as laptops and Pentium 4's.

There's a posix function that returns micro-seconds (timeofday?) and on Win32 you can try QueryPerformanceCounter.

Share this post


Link to post
Share on other sites
Well that’s a bummer, it seams like something so basic it should have been standardized by now. Does boost have anything?

Quote:
Original post by darookie
The only method that works across all modern x86 platforms is the RDTSC instruction. You would, however, have to implement the call in a compiler-specific way (e.g. there are different inline-assembly syntaxes).

Would it be possible to write ASM for all compilers and then determine which compiler is in use with preprocessor directives?

Share this post


Link to post
Share on other sites
What I do is emulate POSIX APIs (the abovementioned gettimeofday and clock_gettime) once for Windows, and game code just uses those. For implementation details of reliable hi-res timer, see article.
I am willing to release the code, but it is difficult to rip out - several thousand LOC spread over several files. Will do that eventually, time permitting.

Share this post


Link to post
Share on other sites
Quote:
Original post by Jan Wassenberg
What I do is emulate POSIX APIs (the abovementioned gettimeofday and clock_gettime) once for Windows, and game code just uses those. For implementation details of reliable hi-res timer, see article.
I am willing to release the code, but it is difficult to rip out - several thousand LOC spread over several files. Will do that eventually, time permitting.


So what you do is basically rewrite gettimeofday for windows that way you can write code that uses gettimeofday on both for either windows or Linux.

Share this post


Link to post
Share on other sites
Exactly. Windows is the odd man out here - everything else [that's relevant] has gettimeofday and/or clock_gettime. Also, adding yet another API for everything (as Boost is wont to do) would mean your users need to learn its interface, whereas gettimeofday et al. are well known.

Share this post


Link to post
Share on other sites
Here's part of my timer class. I don't remember exactly where I got the ASM, but it seems to work pretty well:


void P25DTIMER::GetTick(void* Tick)
{
if(m_TimerType == P25DTMR_CPU)
{
__asm
{
PUSH EDX;
PUSH ECX;
MOV ECX, Tick;
_EMIT 0Fh
_EMIT 31h
MOV [ECX], EAX;
MOV [ECX + 4], EDX;
POP ECX;
POP EDX;
}
}
else if(m_TimerType == P25DTMR_HIRES)
{
QueryPerformanceCounter((LARGE_INTEGER*)Tick);
}
}



Then you can use it like:
float CurrentTick = 0.0f;
GetTick(&CurrentTick);

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this