Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[clock click -milliseconds] resolution - again...

51 views
Skip to first unread message

Jeff Godfrey

unread,
Jun 2, 2004, 3:07:10 PM6/2/04
to
Hi All,

I'm trying to do some animation on a canvas, and I need a high-resolution
timer in order to keep the frame-rates consistent across varying machines.
I went through some troubles with the resolution of [clock
clicks -milliseconds] a number of years ago on Win98, but Kevin Kenny was
able to supply a core patch to fix that problem.

Here's what I have now:

I am testing the resolution of said command using the following code:

console show
while {1} {
puts [clock clicks -milliseconds]
update
}

I have the following 2 PC's, both running ActiveTCL 8.4.5

1. P4 Dell Laptop running WinXP Pro SP1A - 2.6MHz
2. P4 Desktop running WinXP Pro SP1A - 3.0 MHz (hyperthreaded)

On the laptop, the above script returns a unique value each time through the
loop - and the delta between consecutive values is generally 2 ms (not bad).

On the desktop, the above script returns the same value about 15-20 times in
a row. Then, when the value finally changes, the delta is approximately
15-17 ms.

Anyway, the 15-17 ms delta is causing problems in my timing routines.

Any ideas why the above results are *so* different between said hardware
(possibly related to the HyperThreaded CPU)? Any ideas on how to tighten up
the 2nd case?

Thanks for any info.

Jeff


Jeff Godfrey

unread,
Jun 2, 2004, 5:04:39 PM6/2/04
to
"Jeff Godfrey" <jeff_g...@pobox.com> wrote in message
news:10bs9ut...@corp.supernews.com...
: Hi All,


Update...

I just downloaded the latest ActiveTCL 8.5 beta (8.5a2) and tried the above.
The results are the same. Also, I tried the new [clock
clicks -microseconds], but ended up with the same delta values...

Jeff


Roy Terry

unread,
Jun 2, 2004, 6:08:39 PM6/2/04
to

Jeff Godfrey wrote:
>
> Hi All,
>
> I'm trying to do some animation on a canvas, and I need a high-resolution
> timer in order to keep the frame-rates consistent across varying machines.
> I went through some troubles with the resolution of [clock
> clicks -milliseconds] a number of years ago on Win98, but Kevin Kenny was
> able to supply a core patch to fix that problem.
>
> Here's what I have now:
>
> I am testing the resolution of said command using the following code:
>
> console show
> while {1} {
> puts [clock clicks -milliseconds]
> update
> }

For a better idea of what's really happening do
something like this instead

for {set i 0} {$i < 100} {incr i} {lappend x [clock click
-milliseconds]}

foreach m $x {puts $m}
1086213869760
1086213869760
1086213869760
1086213869760
1086213869760
1086213869760
1086213869760
1086213869760
1086213869761
...

puts can be very slow if you're using one of the windows simulated
consoles.

Jeff Godfrey

unread,
Jun 2, 2004, 6:23:41 PM6/2/04
to

"Roy Terry" <royt...@earthlink.net> wrote in message
news:40BE4FE8...@earthlink.net...
:
:

: Jeff Godfrey wrote:
: >
: > Hi All,
: >
: > I'm trying to do some animation on a canvas, and I need a
high-resolution
: > timer in order to keep the frame-rates consistent across varying
machines.
: > I went through some troubles with the resolution of [clock
: > clicks -milliseconds] a number of years ago on Win98, but Kevin Kenny
was
: > able to supply a core patch to fix that problem.
: >
: > Here's what I have now:
: >
: > I am testing the resolution of said command using the following code:
: >
: > console show
: > while {1} {
: > puts [clock clicks -milliseconds]
: > update
: > }
: For a better idea of what's really happening do
: something like this instead
:
: for {set i 0} {$i < 100} {incr i} {lappend x [clock click
: -milliseconds]}


Roy,

Thanks for the advice. Here's my latest test code, though the results
reflect my original findings:

console show
for {set i 0} {$i < 25000} {incr i} {


lappend x [clock click -milliseconds]
}

set y [lsort -unique $x]
foreach m $y {puts $m}

On the P4 3.0 MHz desktop w/hyper threading, I got this result:

1086215177734
1086215177750
1086215177765
1086215177781
1086215177796

That's it - 5 unique values for 25000 iterations.... Again, about 15-16
milliseconds apart each time...

On the P4 2.6 MHz laptop (no hyper threading), I got this result:

-411324103
-411324104
-411324105
-411324106
-411324107
-411324108
-411324109
-411324110
-411324111
-411324112
-411324113
-411324114
-411324115
-411324116
-411324117
< ... truncated ... >

Now, that looks more like it. *Every* millisecond was caught.

Any thoughts?

Thanks,

Jeff


R. T. Wurth

unread,
Jun 2, 2004, 9:04:58 PM6/2/04
to

That 15-17 ms. period sounds a lot to this EE's ears like the
inverse of 60 Hz. So, here's my hypothesis. You must be in
North America (or parts of Japan) where that is the power-line
frequency. Perhaps instead of a really accurate crystal for
the clock, your PC uses the 60 Hz power line frequency? In
that case, 16.6666... ms is the clock period, and there's no
way to get finer. The laptop has to work off of DC batteries,
so they have to spend money on an accurate crystal to get an
accurate clock, and such crystals typically work at much higher
frequencies, which makes for a shorter period.
--
Rich Wurth / rwu...@att.net / Rumson, NJ USA

Jeff Godfrey

unread,
Jun 3, 2004, 8:57:52 AM6/3/04
to

"R. T. Wurth" <rwu...@att.net> wrote in message
news:c9ltfo$1ps...@worldnet.att.net...
: In article <10bs9ut...@corp.supernews.com>, "Jeff Godfrey"

Rich,

Thanks for the input. I would never have though about that, though I *hope*
that's not the case. Does anyone else have any thoughts our input?

Thanks,

Jeff


Kevin Kenny

unread,
Jun 3, 2004, 9:20:09 AM6/3/04
to
Jeff Godfrey wrote:
> I'm trying to do some animation on a canvas, and I need a high-resolution
> timer in order to keep the frame-rates consistent across varying machines.
> I went through some troubles with the resolution of [clock
> clicks -milliseconds] a number of years ago on Win98, but Kevin Kenny was
> able to supply a core patch to fix that problem.

Tcl is close to the ragged edge of what's possible on Windows,
I'm afraid. Let me give a little bit of background here, and
maybe the Windows experts here can figure out what's The Right
Thing.

You will notice that Tcl actually gives you timing to
submillisecond accuracy on many Windows machines. As far
as I know, *no other product attempts this feat without
additional hardware support.* How do we do it? We use a
phase-locked loop to discipline the system performance
counter (which is uncalibrated) to the system clock,
allowing us to interpolate between ticks of the clock.

Alas, the system performance counter is at best imperfect.
Reading the documentation for QueryPerformanceCounter,
http://tinyurl.com/3xp96
we find the bizarre remark (which has been there since at least
NT 4.0):

On a multiprocessor machine, it should not matter
which processor is called. However, you can get
different results on different processors due to
bugs in the basic input/output system (BIOS) or the
hardware abstraction layer (HAL).

In fact, I am well aware of the problem. At least one HAL
for multiprocessor machines implemented the performance counter
with a simple RDTSC instruction, and derived the clock
references for the two CPU's from separate crystals. This
limitation makes the performance counter essentially useless
unless you set the affinity mask of the thread that's using
it to constrain it to one or the other CPU.

Tcl detects systems that have the problem by a simple check.
The initialization code in Tcl_GetTime (tclWinTime.c, starting
around line 282) looks at the performance counter frequency.
If it's at most 15 MHz, it's presumed to be derived from the
8254-compatible real-time clock, and Tcl uses the performance
counter to interpolate between ticks of the system clock.
Otherwise, it's presumed to be the result of RDTSC, or of the
ACPI power timer, and is considered untrustworthy. If the
performance counter is untrustworthy, the code falls back on
using the system clock, which has a much coarser granularity
(up to 20 ms on modern Windows; some versions of Win95 used
55 ms).

This heuristic has been "good enough" in 8.4; it captured by
far the greater number of desktops and laptops, failing only
on a small number of server-class machines. The advent of
hyperthreading has changed all that. On a hyperthreaded machine,
the performance counter is usually derived using RDTSC. Now,
however, both CPU's are aboard the same chip, and share a common
timestamp counter (or perhaps have separate TSC registers that
increment in lockstep - essentially the same thing for the
purposes of this discussion). Now we have a large class of
machines on which QueryPerformanceFrequency will be a couple
of GHz, and the performance counter *is* reliable.

Conservatism is best here. If we use an unreliable
performance counter, we return wildly incorrect times to the
script. If we fail to use a reliable one, we suffer at worst
from imprecision. So what I need is a reliable way to test
whether the performance counter may, in fact, be relied on.

I can manage to grind my way through decoding the information
from CPUID if I must. However, that will require a short
codeburst in assembly language. I'm a trifle reluctant to
introduce that code owing to the obvious maintainability
issues - at the very least, it needs to support both gcc and
VC++, whose assemblers are very different. If there's something
off the shelf in Windows that I can use to get the information,
I've not been able to find it. The coding example that
MSDN provides to get the information (http://tinyurl.com/2g2qt)
suggests that there is no such interface - MS resorts to
assembly language to get the data.

You can track the issue at SF as Tcl bug 965722.
--
73 de ke9tv/2, Kevin

Jeff Godfrey

unread,
Jun 3, 2004, 9:32:38 AM6/3/04
to

"Kevin Kenny" <ken...@acm.org> wrote in message
news:40BF2589...@acm.org...

: Jeff Godfrey wrote:
: > I'm trying to do some animation on a canvas, and I need a
high-resolution
: > timer in order to keep the frame-rates consistent across varying
machines.
: > I went through some troubles with the resolution of [clock
: > clicks -milliseconds] a number of years ago on Win98, but Kevin Kenny
was
: > able to supply a core patch to fix that problem.
:
: Tcl is close to the ragged edge of what's possible on Windows,
: I'm afraid. Let me give a little bit of background here, and
: maybe the Windows experts here can figure out what's The Right
: Thing.

[ ... lots of good background info clipped ... ]

: You can track the issue at SF as Tcl bug 965722.

Kevin,

Thanks for the background info and the insight. I wish I could help with a
fix, but, unfortunately, this is *far* beyond me... On the other hand, if
you, or anyone else, need some code to be tested... .*that* I can do. ;^)

Jeff


0 new messages