See also Re: Time::HiRes not that high on windows, Time::Hires Granularity and In search of a bug in Time::HiRes on Windows..

PC clocks do drift. That's why we have NTP protocols to correct them.

On Win32, Time::HiRes uses two different system apis to produce its wallclock timings.

  1. GetSystemTimeAsFileTime() which is the system clock time. Rather low resolution, but relatively accurate over the long term. Especially if NTP is set up to correct for silicon drift.
  2. QueryPerformanceCounter/QueryPerformanceFrequency which combine to produce very high resolution.

    But, the faster a clock (bistable) runs, the faster any slight variations in the frequency due to chip temperature, voltage variations etc. are magnified into noticable values over the long term.

Time::HiRes uses the high resolution performance timer to generate hi-res timings, but as it can drift over long periods (more than a few seconds; several 100 million ticks), it compares it against the lower resolution, but more stable System clock time, and if it has drifted by more than 0.5 seconds (an arbitrary choice of constant used with HiRes.xs), then it corrects it according to the system clock.

The problem is, the checking and resetting only occurs when you call the GetTimeOfDay() api or one of it's aliases like time(). If you do not call the timer for extended periods, then the timer drift will not be corrected and so you may get larger than 0.5 second of drift.

A simplistic solution to ensure the drift is corrected as early as possible is to set a thread running in the background of your app that simply calls one of the apis at regular intervals

use threads; async{ my $x == time() while Win32::Sleep 0.25; };

If you want to ensure less than 0.5 seconds of drift, re-build Time::HiRes having adjusted the following constant to a suitable value:

#define MAX_PERF_COUNTER_SKEW Const64(5000000) /* 0.5 seconds */

You would still need to ensure that one of the apis gets called regularly as above to ensure the correction takes place in a timely (sic) manner. Adjust the sleep accordingly.

It's also worth considering whether it is the Time::HiRes time that is drifting, or the mutimedia timer that doesn't correct for drift?

I'm not sure how other OSs compensate for silicon drift?


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.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."

In reply to Re: Time::HiRes (un)reliability in Windows/Cygwin ?? by BrowserUk
in thread Time::HiRes (un)reliability in Windows/Cygwin ?? by graff

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.