Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re: The most precise second (timer)

by Fletch (Bishop)
on Nov 26, 2019 at 18:04 UTC ( [id://11109278]=note: print w/replies, xml ) Need Help??


in reply to The most precise second (timer)

Perhaps rather than reinventing wheels use AnyEvent and EV to setup a timer event to be posted every second.

$ perl -MTime::HiRes=time -MAnyEvent -E '$quit = AnyEvent->condvar;$w += AnyEvent->timer( after => 1, interval => 1, cb => sub { state $ctr += 1; say "@{[Time::HiRes::time()]}: FOOP! $ctr"; $quit->send if 10 == + $ctr++; } );say qq{Starting loop};$quit->recv;' Starting loop 1574791289.26471: FOOP! 1 1574791290.26702: FOOP! 2 1574791291.26394: FOOP! 3 1574791292.26511: FOOP! 4 1574791293.26735: FOOP! 5 1574791294.26826: FOOP! 6 1574791295.26665: FOOP! 7 1574791296.265: FOOP! 8 1574791297.26659: FOOP! 9 1574791298.26699: FOOP! 10 $

The cake is a lie.
The cake is a lie.
The cake is a lie.

Replies are listed 'Best First'.
Re^2: The most precise second (timer)
by tukusejssirs (Beadle) on Nov 26, 2019 at 18:39 UTC

    Thanks, but using low-level commands is faster. For us speed (and thus accuracy) is very important.

    I have tested your code on my computer and the average difference from a second is +0.00006222222222222222, which again is more by two decimal places than the difference of the negative_timer (which is -0.000000676723442).

      EV is an interface to the lower-level libev, and AFAIK it's fairly performant. Its "periodic" function claims to work with wall clock time, so you shouldn't have any drift relative to the system clock. That the system clock can drift relative to real time, and that it can be adjusted in jumps, are whole different issues. I'm not sure if the default ntpd supports smooth adjustments to the system clock (Update: apparently, it does), butand I believe chrony does. (I have several systems with a GPS receiver that supports the PPS signal, and I feed that into chronyd to provide a system time that should be quite accurate. I've published some info on that here.)

      use warnings; use strict; use Math::BigFloat; use Time::HiRes qw/gettimeofday/; use EV; my $w1 = EV::signal( 'INT', sub { EV::break } ); my ($cnt, $avg, $prev) = (0); my $w2 = EV::periodic( 0, 1, 0, sub { my $cur = Math::BigFloat->new( sprintf("%d.%06d",gettimeofday) ); if ( defined $prev ) { my $delta = $cur - $prev; $avg = defined $avg ? ( $avg + $delta ) / 2.0 : $delta->copy; $cnt++; } $prev = $cur->copy; } ); EV::run; print "\nAverage over $cnt deltas: $avg\n";

      Sample output from different runs on my system:

      Average over 67 deltas: 1.000005597916695584862263807609389365538 Average over 76 deltas: 1.00012161307435464691799175142220832736 Average over 137 deltas: 0.9997675784785176200109895891945901313775 Average over 442 deltas: 0.9999437250604076389815434390305220372265

        This one looks promising. :)

        It is less punctual than the original code I posted, but I might do.

        But I got something strange when I replaced time() in my original code with gettimeofday: exactly precise seconds (to 5 decimal places). I am not quite sure if that is actually correct–is that just calculated to be precise or it the measurement actually precise? I believe that my measurements are not as precise as yours. :)

        I tried to simplify the test using my $w2 = EV::periodic( 0, 1, 0, sub { print gettimeofday, "\n";} );, but the result was quite unprecise; here’s the output:

        15748078781259 15748078791348 15748078801032 15748078811008 1574807882999 1574807883541 1574807884744 15748078851030 15748078861002 15748078871099 1574807888937 15748078892034 15748078901001 15748078912030 15748078921019 1574807893339M

        Do I do something wrong?

        Anyway, I use chrony, too, but my original timer function (from time to time) still complains about negative time not invented yet. Although, I use default settings of CentOS 7 for chrony–do I need to adjust something to use those smooth adjustments?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11109278]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (5)
As of 2024-04-25 23:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found