Solved

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

Posted on 1998-09-25
12
238 Views
Last Modified: 2010-04-15
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.
0
Comment
Question by:arudolph
  • 5
  • 4
  • 2
  • +1
12 Comments
 

Author Comment

by:arudolph
ID: 1253063
Adjusted points to 200
0
 
LVL 6

Expert Comment

by:snoegler
ID: 1253064
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
 

Author Comment

by:arudolph
ID: 1253065
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
 
LVL 6

Expert Comment

by:snoegler
ID: 1253066
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
 
LVL 6

Expert Comment

by:snoegler
ID: 1253067
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
 

Author Comment

by:arudolph
ID: 1253068
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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 6

Expert Comment

by:snoegler
ID: 1253069
Take a look at www.sysinternals.com - there you'll find lots of information.
0
 

Author Comment

by:arudolph
ID: 1253070
Thanks,  please resubmit an answer so I can accept it (giving you da points).
0
 
LVL 1

Expert Comment

by:NakedTimeMan
ID: 1253071
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
 

Author Comment

by:arudolph
ID: 1253072
Need the assembly code.

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

Thanks
0
 

Accepted Solution

by:
guga earned 200 total points
ID: 1253073
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
 

Expert Comment

by:guga
ID: 1253074
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

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now