• C

Need a Hi-Res timer for use in NT/95/98

I'm looking for some kind of delay routine that's very accurate across processor speeds.  I heard a rumor that the Pentium has an instruction that returns a 64-bit number in nanoseconds?
Does someone have a practical example of it using an inline asm, for compilation in MSVC?

I've tried the 'Zen Timer' routine, but NT doesn't like it  much.  It's resolution is perfect for my use on a '95/'98 machine, but I'm looking for an NT compatible one.

Thanks,
Adam Rudolph

P.S. - I'll give you billing in the freeware program I'm writing.
arudolphAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

arudolphAuthor Commented:
Adjusted points to 200
0
snoeglerCommented:
To access the Pentium/AMD/Cyrix performance counters:

QueryPerformanceCounter() - gives you a 64bit int of the actual value
QueryPerformanceFrequency() - frequency for the counter

The multimedia functions (res 1msec, not 55msec like GetTickCount()):

timeSetEvent
timeKillEvent
timeBeginPeriod
timeEndPeriod
timeGetTime
timeGetSystemTime

The online docs are pretty good on these functions, but if you need further explanation, i
can give you some more information :)
0
arudolphAuthor Commented:
Although your suggestion works, it's a little slow.  By using the QueryPerformanceCounter function, it populates a LARGE_INTEGER structure.  This takes time.  I'd prefer to bypass the WINAPI call completely and use the (RTDSC?) machine language function directly.  It will take fewer clock ticks to do it this way, and I'd get a cleaner timer whose accuracy will be the same on slower Pentium's.
0
Has Powershell sent you back into the Stone Age?

If managing Active Directory using Windows Powershell® is making you feel like you stepped back in time, you are not alone.  For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why.

snoeglerCommented:
Try it ... RTDSC is a ring 0 operation, you'll need to write a device driver for it.
Try getting the DDK from MSDN.
0
snoeglerCommented:
BTW: If you're trying to measure some benchmark - if the time your benchmark takes goes
over 1000msec, the relative error caused by delays thru QueryPerformancyCounter() is
somewhat below 1*10^(-6). Also, the interrupts thru window during your benchmark disturb
the result much much more as the time QueryPerformanceCounter() takes.
For what do you need this timing information?
0
arudolphAuthor Commented:
I'm looking for a timer routine for game programming.  Initially, I've written a game to emulate the old arcade game 'Breakout', so this routine is used for timing the ball motion.  The 'Zen Timer' routine's resolution works well for this purpose (On dos/w3.1/'95/'98) although even it's too slow for a 486.  Not a big deal.  The first attempt at coding this is out on the 'net: http://jr.ne.mediaone.net/BustOut if you are interested in what this is being used for.  The QueryPerformanceCounter seems to take too long when executed twice to give the smallest wait time for the quickest ball motion.  This is why I was looking for in-line asm code to perform this function.  How many clock cycles could it possibly take to execute the in-line function as compared to the API call?  Alot less I would imagine.  I'll try writing the device driver as you suggest.  Thanks.
0
snoeglerCommented:
Take a look at www.sysinternals.com - there you'll find lots of information.
0
arudolphAuthor Commented:
Thanks,  please resubmit an answer so I can accept it (giving you da points).
0
NakedTimeManCommented:
Hey Arudolph

Use the windows NT performance counter, this counts the a starnge frequency that they (MS) came up with.  BUT is VERY accurate.

It can go even to smaller units than millisecs.

I am including a piece of code that I wrote to time a particular time-critical routine in one of my programs.

P.S.
Send me the "Billing in the freeware program" in beer,  I like to call my programs beerware.

Peace


// TIMING OF THE LOOP 080698ADD
//      double   result, elapsed_time, milliseconds;
//      LARGE_INTEGER Frequency, StartTime, EndTime;
//      QueryPerformanceFrequency(&Frequency);
//      QueryPerformanceCounter(&StartTime);

// Code that you want to time.

//      QueryPerformanceCounter(&EndTime);
//      milliseconds = (USHORT)((EndTime.QuadPart - StartTime.QuadPart)/(Frequency.QuadPart / (__int64)0x00000000000003e8));
//      _strtime(TimeStr);
//      sprintf(DebugStr, "TIME: %s MILLISECONDS ON THE LAST ITERATION: %5.5f ",TimeStr, milliseconds);
//      PRINTDEBUG (1000, DebugStr);
// TIMING OF THE LOOP 080698ADD

0
arudolphAuthor Commented:
Need the assembly code.

QueryPerformanceCounter() takes too long to populate the LARGE_INTEGER structure.

Thanks
0
gugaCommented:
This a simple example of Long Timer but it count ticks of processor only. You need tune this timer.

#include <stdio.h>

#define rdtsc __asm _emit 0x0F __asm _emit 0x31

typedef struct _T
{
      unsigned long int low;
      unsigned long int high;
} T;

void _get_rdtsc(T* x);

void main()
{
      T c1,c2;
      c1.low=0;
      c1.high=0;
      c2.low=0;
      c2.high=0;
      _get_rdtsc(&c1);
      printf("%X",c1.low);
      _get_rdtsc(&c2);
      printf("Ticks of processor:=%X\n",c2.low - c1.low);
}
void _get_rdtsc(T* x)
{
      _asm
      {
            mov esi,x
            rdtsc
            mov [esi],eax
            mov [esi+4],edx
      }
}
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
gugaCommented:
Tuning:
 _get_rdtsc(&c1);
 delay(1000);
 _get_rdtsc(&c2);
 time_of_tick=1.0/((float)(c2.low - c1.low));

I don't sure that high word is unused. This progs is simple example only.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.