Re: Time::HiRes sleep does not always work
by holli (Abbot) on Aug 15, 2008 at 08:30 UTC
|
I ran this and got 0 matches on two different machines. What OS are you using? What does it show if you print out the values for $time and $hitime? Are they fractional?
| [reply] [Watch: Dir/Any] [d/l] |
|
I'm using Windows XP and one of the Dell's that I tested on is running Vista.
$time & $hitime are both fractional.
| [reply] [Watch: Dir/Any] |
Re: Time::HiRes sleep does not always work
by zentara (Archbishop) on Aug 15, 2008 at 14:13 UTC
|
UPDATE Try this to see what is happening:
sub sleepy {
my $count = shift;
my $time = gettimeofday;
sleep(0.0001); # Sleep here to ensure unique time
my $hitime = gettimeofday;
print $time - $hitime,' ';
if ( $time == $hitime ) {
$match++;
}
}
I think you are running into some real world factors affecting computers(desktops/laptops). Although we all like to assume that our little machines maintain atomic clock, laboratory quality, time; it's not true. A computer has a little imperfect crystal, that maintains it's time. The crystal is not even temperature stabilized, meaning your clock rate varies with temperature. It's not enough for us to notice, unless there is a bad failure, and the computer circuitry is designed to work with the variations, by using edges of clock waves for synchronization. You also have the kernel's design to consider. There are different schedulers, and the one you would want to use would be the low-latency kernel, that audiophiles use. Otherwise, your kernel may
decide to spend a few microseconds updating your display, rather than process your script. Our computers seem like superfast machines to us, but in a true measure of time, they slog along like they were mired in molasses.
| [reply] [Watch: Dir/Any] [d/l] |
|
If I put in your changes to the routine I get 2000 matches.
So do you think that the reason that the laptops like mine are having this problem could be caused because they are made from lower quality components than say a Dell?
| [reply] [Watch: Dir/Any] |
|
That's my GUESS, the timer support chips in your laptop either are partially defective, or poor quality( low speed). Or some other factor on your motherboard interferes. But after reading tilly's responses, maybe there is some problem in the kernel your slow laptop is using.
| [reply] [Watch: Dir/Any] |
Re: Time::HiRes sleep does not always work
by jethro (Monsignor) on Aug 15, 2008 at 11:48 UTC
|
Read the documentation of Time::Hires: "Any attempt to sleep for X seconds will most probably end up sleeping more than that, but don't be surpised if you end up sleeping slightly less."
Did you check the return value of gettimeofday. What real resolution does it have on your laptop ? Test it with something like this:
while ($i++<100) {
push @g, scalar gettimeofday();
}
print join("\n",@g);
| [reply] [Watch: Dir/Any] [d/l] |
|
I don't quite understand what you're asking.
If I run your piece of code I get 100 prints of the current hi-res time eg: 1219052843.17188
Is that what I should be expecting?
| [reply] [Watch: Dir/Any] |
|
1219059879.53406
1219059879.53407
1219059879.53407
1219059879.53407
1219059879.53407
1219059879.53408
1219059879.53408
1219059879.53408
1219059879.53408
1219059879.53408
1219059879.53408
1219059879.53408
1219059879.53409
1219059879.53409
1219059879.53409
1219059879.53409
That means on my machine there really is a hires timer operating as fast or faster than the resolution of the number I get back. On your machine the loop is either at least 20 times faster than on my machine (very unlikely) or your timer is at least 20 times slower.
Change the 100 in the script to 1000 or more, at least until you see more than one change in the numbers. The difference is the resolution at which your timer works.
For example, if the difference is 0.01, then your timer ticks have a resolution of only 1/100 seconds. My machine above has a resolution of at least 1/50000, i.e. under 20 microseconds
| [reply] [Watch: Dir/Any] [d/l] |
|
Re: Time::HiRes sleep does not always work
by tilly (Archbishop) on Aug 15, 2008 at 18:23 UTC
|
What is the output of gettimeofday() on your laptop?
Based on reading the documentation, Time::HiRes is willing to try multiple strategies for each function. Your problem would make perfect sense if the only emulation of gettimeofday() that your laptop can find is the built-in time() function. However perl2exe compiles the C API call that Perl is looking for into the executable, and so that executable finds the API call that you're missing a library for.
Without a lot of research I can't tell you how to make sure that a useful form of gettimeofday() is properly found on your laptop. | [reply] [Watch: Dir/Any] |
|
The output for gettimeofday() is 121905424846875
I thought that the problem could be caused by a missing function but Dells are running exactly the same Perl dir as me because he copied my Perl directory (so he didn't have to download all the modules)
| [reply] [Watch: Dir/Any] |
|
Hmph, pesky rounding keeps the decimal from being visible.
Try printing gettimeofday() - time(). My suspicion is that they are exactly the same. And the cause is that at runtime Perl checks whether it can load the system gettimeofday function, and can't find it on one machine but can on another, leading to different results.
| [reply] [Watch: Dir/Any] [d/l] |
|
|
|
Re: Time::HiRes sleep does not always work
by BrowserUk (Patriarch) on Aug 18, 2008 at 10:57 UTC
|
Which version of Time::HiRes are you using?
There was a bug in versions < ~1.53 that meant it only used a low-resolution timer. This what later enhanced with the use of a short period, high resolution timer.
However, there were still some circumstances, particularly under the aucpices of the debugger, in which the resolution seemed to fall off quite badly. See In search of a bug in Time::HiRes on Windows..
You mentioned Vista somewhere in one of your replies. Are all the systems running Vista? Maybe there is some incompatibility.
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [Watch: Dir/Any] |
|
| [reply] [Watch: Dir/Any] |
|
#! perl -slw
use strict;
use Time::HiRes qw[ gettimeofday time ];
use Win32::API::Prototype;
ApiLink( 'kernel32', q[
BOOL QueryPerformanceCounter( LARGE_INTEGER *lpPerformanceCount )
]) or die $^E;
ApiLink( 'kernel32', q[
BOOL QueryPerformanceFrequency( LARGE_INTEGER *lpPerformanceCount
+)
]) or die $^E;
sub int64_to_NV {
my( $lo, $hi ) = unpack 'VV', $_[ 0 ];
return $hi * 2**32 + $lo;
}
my $frequency = ' ' x 10;
QueryPerformanceFrequency( $frequency ) or die $^E;
print 'Counter changes ', int64_to_NV( $frequency ), ' times/second';
for ( 1 .. 10 ) {
QueryPerformanceCounter( $frequency )or die $^E;
print 'QPC: ',int64_to_NV( $frequency );
}
printf "GToD: %.8f\n", scalar gettimeofday() for 1 .. 10;
printf "Time: %.8f\n", time() for 1 .. 10;
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [Watch: Dir/Any] [d/l] |
|
|
|
Re: Time::HiRes sleep does not always work
by ikegami (Patriarch) on Aug 22, 2008 at 03:37 UTC
|
What version of Time::HiRes do you have? You want at least 1.53 on Windows.
Update: Oops, already mentioned. I missed it when I checked earlier. | [reply] [Watch: Dir/Any] |
Re: Time::HiRes sleep does not always work
by psini (Deacon) on Aug 15, 2008 at 08:31 UTC
|
sleep Sleep has a granularity of 1 second, so it is useless to call it with a fractional value.
Rule One: "Do not act incautiously when confronting a little bald wrinkly smiling man."
| [reply] [Watch: Dir/Any] |
|
Time::HiRes can export a sleep method which overrides the built in.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
| [reply] [Watch: Dir/Any] |
|