Free Digital Watch!

Mathimagics
03-06-2004, 05:54 PM
Note: This demo is aimed at Advanced- (or beyond) level API programmers only!

From the people who brought you Snibbo for Visual Basic, here's the latest in digital watch technology! yes, if you're a serious eXtreme Adventure Sports Programmer, you're probably always running 100 nanoseconds late. Go on, admit it!

Dr Memory presents dmClockLib, a handy little gadget we knocked up this afternoon - it's the timepiece for the discerning chronologist, it's the time-slave's next nano-fix, it's the CPU clock.



Choosing the Right Digital Wtach

Serious VB timekeepers will tell you that GetTickCount is relatively useless as a performance analysis tool - just try to measure the time it takes to execute a modest chunk of VB code on your 1ghz CPU and you'll find it's like trying to measure a biscuit crumb with a bargepole. ;)

Our friendly OS hosts have given us the QueryPerformanceCounter function, which reads a 64-bit clock provided not by your CPU, but your inboard clock.

These clocks all (as far as I know), use the NTSC standard clock rate, which is approx 3.6MB. The QueryPerformanceFrequency function returns the frequency (ticks-per-second) of this clock, and you will find that almost invariably it will be this exact value:

Const QPF = 3579545


Now, a 3.6Mhz clock is certainly better than a 0.001Mhz one - and in fact the millisecond clock (i.e. GetTickCount) only seems to get updated about 30 times a second anyway.

QPC has one flaw, however - the fact that it is held to a standard value means that CPU clocks have been steadily outpacing it ever since the first PC reached a 3Mhz rate - that was a long time ago, in case you hadn't noticed.

A Pentium P3 like my old desktop, at 733Mhz, is clocking at almost 250 times the NTSC rate. So we come up against that very same original performance measurement problem!

We've simply shifted the problem into a different scale - now it seems we are trying to measure a grain of sand with a broomstick! :p



Enter the CPU Clock

You're thinking, for heaven's sake! Why don't they just give us the CPU's own clock?

That sure makes good sense, doesn't it!

A clock that is always as fast as your CPU is going to be faithful no matter where you take it - you shouldn't miss a beat when you upgrade that CPU.

But there's no generic CPU clock access under Win32.


Why isn't it provided through the Win32 API?

That's simple, it's because a readable CPU-rated clock is an entirely hardware dependent feature. If the CPU does not offer an OP code that can read the clock, you have a big problem, as attempting to execute an invalid instruction wil trigger a General Protection Fault.

I'm not sure when Intel first introduced this capability - the clock read op code is called RDTSC - a related one called CPUID was introduced around the time the i486 came out.

In fact, one of the values that can be queried with CPUID is a processor signature mask, and Intel sets a bit in there that tells you whether the RDTSC instruction is available.

All Pentiums have the readable clock, probably all Intel CPU's made since the i586 do, and I read somewhere that Athllon CPU's have it too, so it's probably supported on a majority of PC's today.


The dmClockDemo Program

What I've done is provided a small DLL, writen in PowerBasic. It's about 50 lines of code all up (comments and whitespace excluded).

The DLL exports a couple of simple functions to calculate QPC clock sample intervals, no big deal, but it also offers the same functions for the CPU clock.
(PowerBasic supports in-line assembler code insertion).

The demo program is a simple VB form that displays a few examples of making calls, including:

Measuring the cost of reading the clock


A simple way to measuring your CPU's clock rate
To measure your CPU speed, we just take any 2 equivalent interval measurements, one from QPC, one from the CPU. Your CPU speed is given by:

CPUrate = CPU / QPC * QPF

I get a steady 731.5 average reading on my 733Mhz Pentium, so that's accurate to just 1/5 of 1%.



Caveat Emptor

Prudence (an occasional visitor round here) suggests that if you have any reason to suspect your CPU might not have this clock, then be aware that the program will trigger a GPF if the instruction is invalid. That's all, just like a dud pointer would.

It shouldn't be a BSOD case, just another fatal error in the life ... you just need to be aware of this before you run the demo the first time!


Source code included

I've included the source code for the PB dll, so if you have PowerBasic you can change it, or adapt it in some other form.

If you ever consider distributing VB software that uses this DLL, you'd be well advised to install a GPF "soft-landing" handler in your front-end! Just in case some of your customers are still running on i386's!!!!

See the SetUnhandledExceptionFilter api function. If you aren't using this feature already, you should be (unless you never get a GPF, of course!)


Anyway, we hope you get the resolution you seek from this little toy!

Enjoy!


Dr Memory

Mathimagics
03-07-2004, 02:53 AM
The sub-microsecond accuracy achievable with the CPU clock is evident from the test results shown above for a 733mhz Pentium 3 CPU.

The estimated cost of a call to the dmCPUinterval function is around 240-280 ticks. This figure is obtained from making several successive calls and reporting the last (or an average) return value.

For a 733mhz clock, this result represents a measurement interval of just 1/3 of a micro-second.

Faster CPU's should yield proportionally smaller values.

Mathimagics
03-07-2004, 06:23 PM
The function SetUnhandled ExceptionFilter has a name too long to be indexed.

This post is just to register the split form above - so you and I can find our way back to this thread when we want to, with a forum search term like Setunh*

EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum