Jump to content
  • Advertisement
Sign in to follow this  
Ned_K

Looking for low-level clock/timer info

This topic is 4872 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm looking for some specific info on the system clock that I couldn't find in the technical documents. Correct me if I make any incorrect statements or assumptions. The various windows timer functions have to access the CPU clock in order to keep time, or, they have to access an intermediate windows clock (in memory) which in turn has to access the CPU clock (right?). What specifically are these windows functions accessing (as in WHERE)? Is there a fixed register on the ia-32 architecture with the timer running? Can I access the clock directly via assembly? How? Also, does windows have a timer function residing at a separate location in memory? If so, what address? Thanks.

Share this post


Link to post
Share on other sites
Advertisement
Does this still apply to today's processors?
http://www.eecg.toronto.edu/~de/RDTSCPM1.pdf

Also found this, but it's old...
http://www.geisswerks.com/ryan/FAQS/timing.html

Share this post


Link to post
Share on other sites
Ahh, I think I got it with this one:
http://www.devx.com/SummitDays/Article/16293/1411/pdo/29FD2B1375EBAC824CE7A420FAC318F4:3835
(Anyone know equivalent info for AMD?)

typedef struct _BinInt32
{
__int32 i32[2];
} BigInt32;

typedef struct _BigInt64
{
__int64 i64;
} BigInt64;

typedef union _bigInt
{
BigInt32 int32val;
BigInt64 int64val;
} BigInt;


This data structure consists of the union of a 64-bit integer (a Windows defined __int64 item) and two 32-bit integers, specified as __int32 items. The following code loads each of the two 32-bit halves of the __int64 data item with high- and low-order parts of the clock counts obtained from the operating system:


BigInt start_ticks, end_ticks;

_asm
{
RDTSC
mov start_ticks.int32val.i32[0], eax
mov start_ticks.int32val.i32[4], edx
}

This code works fine under Visual Studio .NET 2003 and should work on previous versions of the C/C++ compiler. RDTSC (ReaD Time Stamp Counter) is an assembly command that loads the EAX and EDX registers with the contents of the time-stamp counter, which tracks the clock cycles. After executing this code, start_ticks contains the full clock count. Call the same code replacing start_ticks with end_ticks and subtract the latter for the former to see how many clock ticks have expired.

To print this _int64 value, use the following printf() mask:


printf ( "Function used %I64Ld ticks\n", end_ticks.int64val.i64 -
start_ticks.int64val.i64 );


The assembly code above (the block preceded by _asm) is handled properly by the C compiler which carefully saves the EAX and EDX registers automatically before they're overwritten.

The Win32 function QueryPerformanceCounter() does pretty much the same thing. Its sole parameter is a long pointer to a counter variable. It returns 0 (or actually FALSE) if the function fails. However, the code presented above enables you to get around the black box of the Windows call and to reproduce similar functionality in non-Windows operating systems that run on Intel processors.

Using the Timing Figures
If you need to translate the clock counts into true elapsed time, divide the results by your chip's clock speed. Remember that the "rated" GHz is likely to be slightly different from the actual speed of your chip. To check your chip's true speed, you can use several very good utilities or the Win32 call, QueryPerformanceFrequency(). Two utilities I recommend are Intel's own "Processor Frequency ID Utility." It can be downloaded at no charge. This tool also presents considerable additional information about the processor. Even more data is available through H. Oda's utility, wCPUID, which can be downloaded and used at no cost. Don't let the fact that this is a Japanese site dissuade you. This is terrific software.

Both utilities will give you the exact clock Hz. Take that number and divide it into the clock count you obtained from the previous routines and you will have a timer with micro to nanosecond resolution. QueryPerformanceFrequency(), which likes its counterpart takes a long pointer into which the frequency in counts per second is placed. It returns 0 or FALSE on error.


Share this post


Link to post
Share on other sites
rtdsc works on AMD

The problem with it is that it's per CPU/core. It won't work "right" on a multi-core system nor on a P4 or laptop that changes it's clock speed. It tells you the elapsed CPU ticks so it does what it is intended to do, but it's no good as a clock in these cases.

You're supposed to executed a so-called serializing CPU op-code prior to using rtdsc, such as cpuid.

Share this post


Link to post
Share on other sites
Quote:
Original post by Shannon Barber
rtdsc works on AMD

The problem with it is that it's per CPU/core. It won't work "right" on a multi-core system nor on a P4 or laptop that changes it's clock speed. It tells you the elapsed CPU ticks so it does what it is intended to do, but it's no good as a clock in these cases.

You're supposed to executed a so-called serializing CPU op-code prior to using rtdsc, such as cpuid.


Ok, thanks. I'll google that now.

Share this post


Link to post
Share on other sites
What exactly are you talking about? The system clock (system synchronization) or the real time clock (date/time/calendar)? I don't know Windows programming but I would assume that it has a function that reads the time/date from the RTC if thats what you are wondering. The RTC is just a special integrated circuit that can keep time even with no power to the system, sometimes its also referred to as the CMOS depending on the system, or the system clock by those who aren't fluent in hardware.

It seems like using the RTC would be easier than messing around with RDTSC if all you want to do is keep time with a fairly decent accuracy (seconds).

Share this post


Link to post
Share on other sites
Quote:
Original post by Caitlin
What exactly are you talking about? The system clock (system synchronization) or the real time clock (date/time/calendar)? I don't know Windows programming but I would assume that it has a function that reads the time/date from the RTC if thats what you are wondering. The RTC is just a special integrated circuit that can keep time even with no power to the system, sometimes its also referred to as the CMOS depending on the system, or the system clock by those who aren't fluent in hardware.

It seems like using the RTC would be easier than messing around with RDTSC if all you want to do is keep time with a fairly decent accuracy (seconds).


System clock; playing around with timers for a program. The best way to learn is to do, even if I do it and it's kludged.

Share this post


Link to post
Share on other sites
Some links to get you started:
Timing Pitfalls and Solutions [brief coverage of prevalent time sources]
Timing on the PC family under DOS [pure gold; covers ALL timing possibilities of ~1995]

Actually there are a multitude of possible time sources. QueryPerformanceCounter only uses RDTSC on MP systems; it usually goes for the PM aka ACPI timer (3.57MHz), and 8254 PIT (1.19MHz) on older systems. A new timer called HPET is also slowly coming into use.

As to direct reading from asm: most people don't know this, but Windows maps a page with all sorts of interesting goodies into your process at 0x7FFE0000 (see _KUSER_SHARED_DATA). You can read the tick count directly there (and in fact this is nothing other than what GetTickCount does; the technique avoids a kernel transition).

HTH+Good luck!

Share this post


Link to post
Share on other sites
Quote:
Original post by Caitlin
What exactly are you talking about? The system clock (system synchronization) or the real time clock (date/time/calendar)? I don't know Windows programming but I would assume that it has a function that reads the time/date from the RTC if thats what you are wondering. The RTC is just a special integrated circuit that can keep time even with no power to the system, sometimes its also referred to as the CMOS depending on the system, or the system clock by those who aren't fluent in hardware.

It seems like using the RTC would be easier than messing around with RDTSC if all you want to do is keep time with a fairly decent accuracy (seconds).


*ahem* I only know some generalities about timing - I am assuming they are the same for every chip/arch/OS, but this is the disclaimer that it might not be.

In reality, only the operating system(linux, for example) reads the RTC, which is a timing chip that continually updates the CMOS with the current time, even while the system is off. (Ironically, the "CMOS" the RTC uses is one of the only chips in the modern pc not made using CMOS technology)

When the OS boots, the RTC(the hw clock) is read and stored. Rather than rely on the RTC, the OS uses the much higher resolution timing interrupt to regularly update the stored time value(the softclock). When the OS goes into a regular shutdown (not straight power-off) the softclock is "saved" into the hw clock.

In conclusion, unless you have very unusual timing requirements, use whatever multi-core-safe facilities your OS provides. For example, gettimeofday(). Dunno about windows. perhaps QueryPerformanceCounter or timeGetTime?

Edit: also, be careful confusing the RTC(hw clock), softclock, and the CPU clock. All are 3 different things :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!