Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re^3: The most precise second (timer)

by haukex (Archbishop)
on Nov 26, 2019 at 20:54 UTC ( [id://11109287]=note: print w/replies, xml ) Need Help??


in reply to Re^2: The most precise second (timer)
in thread The most precise second (timer)

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

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

    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?

      the different length of your results, and especially the trailing "M" in the last line made me suspect gettimeofday doesn't return integers. A look into Time::HiRes confirms
      gettimeofday ()
      In array context returns a two-element array with the seconds and microseconds since the epoch. In scalar context returns floating seconds like Time::HiRes::time()
      print evaluates its arguments in array context. So you could either change $, ($OUTPUT_FIELD_SEPARATOR) to somethng visible, or force scalar context by printing scalar gettimeofday or gettimeofday+0.
      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'm not sure what you mean exactly, maybe you could show the code you're referring to that shows this effect? Note that Time::HiRes provides its own implementation of time, could that have something to do with it?

      print gettimeofday, "\n";

      soonix answered that one: in the list context of print, gettimeofday returns two values, and you're seeing the concatenation of the two. That's why I used sprintf("%d.%06d",gettimeofday) - using getttimeofday in scalar context returns a floating-point number; since I was using Math::BigFloat I didn't want any floating-point imprecisions, so I used a string instead.

      Although, I use default settings of CentOS 7 for chrony–do I need to adjust something to use those smooth adjustments?

      Sorry, it's been a while since I worked with it in detail, I'm certainly not an expert. But throughout its documentation you'll see references to it slewing the clock, so I believe its normal mode of operation is to change the system clock's frequency slightly to adjust the time, instead of adjusting the time itself, which would result in jumps. And just to make sure: You mean you're running chronyd on this machine, not just on your NTP server and using a regular NTP client on the local machine?

      Update: Take a look at the makestep and perhaps maxslewrate directives in your configuration - and in general I'd suggest a thorough read of those docs. Update 2: From initstepslew:

      In normal operation, chronyd slews the time when it needs to adjust the system clock. For example, to correct a system clock which is 1 second slow, chronyd slightly increases the amount by which the system clock is advanced on each clock interrupt, until the error is removed. Note that at no time does time run backwards with this method. On most Unix systems it is not desirable to step the system clock, because many programs rely on time advancing monotonically forwards.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (6)
As of 2024-04-25 18:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found