Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Time::HiRes sleep does not always work

by tone (Novice)
on Aug 15, 2008 at 07:58 UTC ( #704489=perlquestion: print w/ replies, xml ) Need Help??
tone has asked for the wisdom of the Perl Monks concerning the following question:

Hi fellow monks,

I'm having a problem with the sleep function in the Time::HiRes module in another script of mine so I quickly wrote the code below to test and this is what happens when I run it with sleep set to (0.001):
  • I get roughly 1750 matches on my laptop
  • If I run this on other laptops like mine I get the same results
  • On a pair of Dells (one faster and one slower than my laptop) I get 0 matches
  • If I compile the code with perl2exe(for this test only) and run it on my laptop I get 0 matches
Also if I run it with sleep set to (0.02) I get 0 matches on my laptop. So can the Monks explain why this is happening?
use strict; use warnings; use Time::HiRes qw(sleep gettimeofday tv_interval); my $test = 0; my $match = 0; while ( $test < 2000 ) { &sleepy($test); $test++; } print "A match occurred $match times"; sub sleepy { my $count = shift; my $time = gettimeofday; sleep(0.001); # Sleep here to ensure unique time my $hitime = gettimeofday; if ( $time == $hitime ) { $match++; } }

Comment on Time::HiRes sleep does not always work
Select or Download Code
Re: Time::HiRes sleep does not always work
by holli (Monsignor) 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?


    holli, /regexed monk/
      I'm using Windows XP and one of the Dell's that I tested on is running Vista. $time & $hitime are both fractional.
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."

      Time::HiRes can export a sleep method which overrides the built in.


      holli, /regexed monk/

        Shame on me. :-(

        I really should not believe I'm awake at this time in the morning...

        Rule One: "Do not act incautiously when confronting a little bald wrinkly smiling man."

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);
      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?

        That means while perl was busy printing 100 time stamps there was absolutely no change in the time stamp itself. On my maschine every few (4 or 5) values the time stamp changed, but only the minimal step the floating point number could show:

        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

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.


    I'm not really a human, but I play one on earth Remember How Lucky You Are

      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?

        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.

        I'm not really a human, but I play one on earth Remember How Lucky You Are
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.

      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)

        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.

Re: Time::HiRes sleep does not always work
by BrowserUk (Pope) 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.

      I'm using version 1.9712

      Out of the five systems I tested on only one is running Vista and all the others are on XP.

        Could you post the output from the following on one machine that gives good results and one that gives bad:

        #! 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.
Re: Time::HiRes sleep does not always work
by ikegami (Pope) 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.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://704489]
Approved by Arunbear
Front-paged by betterworld
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (10)
As of 2014-12-22 11:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (116 votes), past polls