Hi Matt,

On Wed, September 10, 2014 22:46, Matt Wilmas wrote:
> Hi Anatol, all,
>
>
> Sorry for top post...  Stas must be getting confused with all these
> details! :-)  Is Pierre going to weigh in?  Are there any other Windows
> people?
>
> While I don't think I'd disagree with much of what you've said, I don't
> see that using my patch is *causing* or *creating* new issues that you're
> referring to.  Whatever is broken with Windows is still the *same* with
> what's there now since last year.
>
> All I wanted to do, that I think Windows users want, is make microtime()
> at least resemble *micro* time (very well, resolution-wise) so that it *is*
>  suitable for performance measurements.  It's useless for that now.  And
> it
>
> happens to fix the uniqid() problem to boot.
>
> I don't think there were [m]any issues over 10+ years using microtime()
> for that?  It was that implementation's errors over time (which mine
> doesn't have) that were revealed when compared to another value, like
> REQUEST_TIME[_FLOAT].
>
>
> Maybe I used the wrong subject wording or NEWS file update -- I'm not
> trying to improve actual "accuracy" over what's available now -- just
> insure that
>
> it stays accurate as it can be (within range) with respect to the current
>  time, unlike the old implementation.
>
> So things are MUCH better for microtime() useable resolution and
> uniqid().
>
> What are some actual usage scenarios that my implementation would make
> WORSE
> than they are now?  I don't see how...  It seems you're against the idea,
> in principle, of it working at all like the old way (in a good way)? :-/
> The
>
>
> patch doesn't make all these new problems like you are suggesting.
>
> More below...
>
>
>
> ----- Original Message -----
> From: "Anatol Belski"
> Sent: Tuesday, September 09, 2014
>
>
>> Hi Matt,
>>
>>
>> [...]
>>
>>
>> coming to this right now. I'm just responding here as otherwise we'd
> have
>> three parallel threads to follow, not handy.
>>
>> I've tested your new variant and it doesn't show $t1 < $t0 on the same
>>
> VM.
>
>> However I still see an issue. The main issue that it tries to solve a
>> hardware bug with math, that can work or not.
>
> I'm not trying to solve a hardware bug at all with math.  The idea is
> only
>
> to indicate the *certain* passage of time between calls while the
> returned
>
> time, otherwise, remains the same (as one example).
>
>
>> Furthermore, looking closer
>> at the math in the patch, I don't think it's correct. Obviously we
> neither
>> should care about winxp at this times, nor about vista. Regarding win7,
>>  there are still too many issues to have a stable synchronizable timing
>>
> in
>> high resolution. You can agree or not, here are just the facts:
>
> You are talking about "synchronizable," etc. but I'm not trying to do
> anything like that.  Just a time that usually moves forward (except window
>
>
> of x amount of time it could stay the same if clock is advancing *very*
> slowly (QPC too far ahead and "clamped" to max); still better than now).
>
>> - time-of-day clock accuracy depends on tick frequency (RTC interrupt)
>> and/or additionally on HPET - QPC can be based on HPET, RDTSC, ACPI, etc.
>>  - the interrupt frequency depends on HW used
>>
>
> And on timer resolution, right?  AFAIK the default timer resolution
> (lowest)
> is always equal to the time_update_rate (lpTimeIncrement).  Again, not that
>  this matters much anyway, since currently results are same or worse than
>  my implementation.  Mine doesn't make anything worse.
>
>> - QPC is not synchronizable to an external source, while time-of-day
>>
> clock
>> is
>
> See above again. :-)  Only moving the micro time forward when it doesn't
> otherwise change.
>
>> - QPC and partly time-of-day clock additionally depends whether it's a
>> real HW or a VM, number of processors, thread safety, function call
>> latency, etc. - while retrieving QPC is cheap, time-of-day clock will
>> lead to loosing some microseconds
>
> I was actually wondering about the QPC latency (but not an issue raised
> before) on diff systems...  I don't see why there'd be a delay getting
> system time.  Regardless, I can call microtime() on my system (older
> Q9400)
> 2 million times/sec. (inc. loop overhead), so not losing microseconds when
>
>
> half the calls return the same value. :-)
>
>> - there are also some new HW which provides multimedia timing chips
>>
>>
>> For more I'd just mention the site you already was linking to (did read
>>  that also a lot before), and especially to this doc
>> http://www.windowstimestamp.com/PartIIAdjustmentofSystemTime.pdf
>>
> starting
>> at 4. As well as the MSDN pages for the corresponding functions.
>>
>> The consequence of all this is that it's completely unpredictable to
>> mix QPC and time-of-day clock. There's no guarantee that time update
>>
> interval
>> will match the interrupt interval. Back to the math in the patch,
>> lpTimeIncrement from  GetSystemTimeAdjustment() will be constant, but
>> lpTimeAdjustment can change. You currently don't take it in account.
>> lpTimeAdjustment can be changed by a SetSystemTimeAdjustment() call,
> from
>> an arbitrary source like some program or NTP update. Time adjustment
>> can be disabled (and effectively that's not handled atm). That means
>> from
> the
>> patch
>
> I already said how I'm purposely not taking any SetSystemTimeAdjustment()
>  calls into account (besides the fact that it's probably never used).
> Complicates things much more than is needed to simply estimate time
> passage between actual system time updates.  The clock changing +/- 1
> sec/hour (that's probably getting extreme as far as errors) is less than 5
>  microseconds per 1/64 second update interval.  Doesn't matter when it's
> less than any fluctuation anyway.  Certainly not an issue compared to now!
>
>
>> ts = target - time_update_rate
>>
>> doesn't bring you to the time at the previous update interval.
>
> If the estimate is behind (either over time or because clock jumped
> forward), that simply brings it to the minimum amount within range (so it
> "jumps" as little as acceptable).  The only way that could *not* be
> at/within the previous update interval is if the clock was updating
> *slower*
> than normal (TimeAdjustment < TimeIncrement) in which case the estimate
> would be *ahead*, not behind.
>
>> Say when
>> lpTimeAdjustment == lpTimeIncrement, there were no gain at all (same as
> if
>> time adjustment were disabled).
>
> There's always some gain -- can't stop the clock. :-)  But if could,
> still
>
> no worse than now!
>
>> That's why I meant
>> GetSystemTimeAdjustment() should be called as frequently as
>> gettimeofday(). From
>>
> http://msdn.microsoft.com/en-us/library/windows/desktop/ms724394%28v=vs.8
> 5
> %29.aspx
>
>> I read the following:
>> =============
>> For each lpTimeIncrement period of time that actually passes,
>> lpTimeAdjustment will be added to the time of day. If the
> lpTimeAdjustment
>> value is smaller than lpTimeIncrement, the system time-of-day clock
>> will advance at a rate slower than normal. If the lpTimeAdjustment value
>> is larger than lpTimeIncrement, the time-of-day clock will advance at a
> rate
>> faster than normal. If lpTimeAdjustment equals lpTimeIncrement, the
>> time-of-day clock will advance at its normal speed. =============
>>
>
> Yes, I know all that...
>
>
>> The conclusion - while QPC is constant (or actually should be), the
>> time-of-day clock might shift at an arbitrary rate. Taking in account,
>> that the update interval can most likely be not the same (for instance
>> RDTS vs PM clock), the result of the math is arbitrary. For more,
>> GetSystemTimeAsFileTime() and GetSystemTimeAdjustment() will surely take
>>  several microseconds to complete, which add to the uncertainty. So
>> even when used, they should be feched right after QPC. At the end, we
>> have "some" value which passes into the range between the current QPC
>> and the time-of-day clock values, but it's obviously not the value one
>> could
> call
>> even approximately correct. The uncertainty might be low enough to fit
>> into the max resolution (say 300us were the max resolution and 30ms the
>>  uncertainty), however that's just a hope.
>>
>> For an application which really matters about the microsecond
>> resolution it'll be not suitable. The timestamp will be just phony.
>> That's what i
>> meant with the example of the ebay bid, apart from net latency of
> course.
>> But ebay uses the millisecond resolution anyway, like actually almost
>>
> any
>> real world app nowadays, still. It's more like example when you have
>> PHP
>> with this patch and try to communicate with another machine which is
>> synchronizing time say per NTP and as in that case exact timing would
>> matter, how much discrepancy will it have? After one month of running
>> an FCGI process? And so on.
>>
>
> Discrepancy?  No more than now.  After running for any amount of time?
> No
>
>
> more than now.
>
> It would be very hard to synchronize a Windows system's time anyway (I
> guess on windowstimestamp.com it's trying to help with that, but who's
> using that?), so the bidding resolution stuff is almost moot anyway --
> problem is same now, my patch doesn't hurt anything like I'm saying.
>
> You can't do any synchronized communication now either anyway.  How would
>  you?  Even IF a clock was truely synchronized, there's no way in PHP (or
>  anything) to wait for/until a certain time to the millisecond...
>
> But of course this is all theory stuff that applies now/regardless and
> nothing to do with my patch implementation.
>
>> IMHO how it looks with pre win8 - the time-of-day API is not suitable
>>
> for
>> performance measurements. I actually always presumed that it was your
>> goal. For this goal the hrtime stuff can be used where you even can
>> measure with pure QPC ticks when on a fast machine (say when you're out
>>
> of
>> even ns range). As if we cannot provide a valid synchronizable
>> timestamp with QPC, the qualitative performance measurement is easy done
>> using relative time intervals.
>
> Most would not be using something not commonly available...  And
> regarding
>
> relative time intervals, couldn't QPC counter roll over on some system
> (like
> VM)?  Or it handles that somehow?  Or be out-of-sync between cores on some
>
>
> hardware with XP?
>
>> May I suggest you to pack your work into a PECL extension, or maybe
>> even merge with hrtime. As there are several aspects anyway where we
>> have an issue, more or less. For example uniqid() you've mentioned. Or
>> actually, usleep() IMHO - much more of issue than microtime currently as
>> the resolution used there can be much worse. Anyway, it can come back to
>>
> core
>> after it was good tested, is well thought and solid. That's what I
>> would suggest to do.
>
> Yeah usleep() is way more coarse on Windows because of timer res., right?
>  Nothing can be done about that.
>
>
>> Best regards
>>
>>
>> Anatol
>>
>
> Thanks,
> Matt
>
>
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>
>
I'm not against the principle in general, just saying that I have a
serious doubt that it works as you expect. That's why doing this overtime
homework after reading your mail. Firstly - the argument that time
adjustments aren't used is simply not true. Here's a simple snippet which
can check what the time adjustment is

while (1) {
        DWORD adj, inc;
        BOOL disabled;

        GetSystemTimeAdjustment(&adj, &inc, &disabled)

        /* Increment is 156250 which is the number of the ns units, so move it 
to
ms:
         * 156250 * 100 ns / 1000 == 156250/10 us/s == 15625 us/s = 15.625 ms/s
         * */
        if (!disabled) {
                printf("adjustment=%fms increment=%fms disabled=%d 
gain=%fms/s\n",
adj/10000.0, inc/10000.0, disabled, 1000.0*((adj - inc)/(double)inc));
        } else {
                printf("time adjustment disabled\n");
        }
}



The windowstimestamp.com describes the increment values which apply to
most systems I test on, 156250 is one of those and is described as RTC
Periodic Interrupt at 64 Hz (see the document from my first mail). To my
experience, the system clock will advance up to +/-90us every
lpTimeIncrement, the smallest I've seen was like 20us. The
lpTimeAdjustment can change after any update. However when a system uses
HPET, it'll replace the RTC interrupt. So that's for one.

Furthermore, sometimes GetSystemTimeAdjustment() switches to disabled,
sometimes to enabled. The doc says, lpTimeIncrement and lpTimeAdjustment
only make sense when lpTimeAdjustmentDisabled is false.

GetSystemTimeAsFileTime() to my experience costs up to 20us or more. Just
to call it. Here is the snippet to illustrate:

__int64 freq, start, end;
double elapsed
FILETIME tod;

if (!QueryPerformanceFrequency((LARGE_INTEGER *)&freq)) {
        return 1;
}

QueryPerformanceCounter((LARGE_INTEGER *)&start);

GetSystemTimeAsFileTime(&tod);

QueryPerformanceCounter((LARGE_INTEGER *)&end);

elapsed = ((end - start)*1000000000)/freq;

printf("GetSystemTimeAsFileTime took %fns\n", elapsed);

Measuring it with QPC. Despite MSDN says QPC might cost like 20ns, in my
test I can't even measure it in nanoseconds, so it's a matter of ticks.
It's easy to modify this snippet to measure QPC as well.


So the scenario like

- get QPC (cheap)
- get time-of-day (20ms uncertainty)
- get correct time adjustment (have to measure that as well, but still
some ms lost)
- calculate

IMHO the result isn't usable by the best will, looks more like a random
value within some range. Here at the end a bit of the ASCII art I've
prepared as an example:


QPC 200us sample +/- 1 tick
-|----------|----------|----------|----------|----------|----------|----------|----


PM clock advance with adjustment + 20us to get the time + Xms to get the
adjustment
-|----------|----------|----------|----------|----------|----------|----------|----
           50us       50us      -50us        0us        90us       90us   
    .....


PM clock interrupts
---|------|------|------|------|------|------|------|------|------|------|------|---
   1      2      3      4      5      6      7      8      9      10    
11     12

You can see that while sampling on seemingly same interval with QPC and PM
clock, a situation is possible that the time-of-day clock could have been
updated more than once inbetween. So this is a hardware issue, say one is
using TSC and the other PM interrupt or HPET, plus time adjustment. As you
mentioned, whether QPC can rollover, also a big question (which adds more
instability actually) as it depends on the source used. On the modern HW
it usually uses TSC which is stable, on different systems however it can
have drifts with the system clock, even on linux as mentioned in earlier
mails. QPC will anyway care about anything like multicore or threads.

I understand your intention to fulfill the user expectation, however for
the performance tests much more qualitative results can be achieved with
QPC and relative time intervals. That's for the answer what worse could it
make as it was or is. For the normal usage, the microtime improvement were
of course important, however with some feasible scenario. Also, even if
they blame the current solution - it works well for many systems and
scenarios. Just unlucky it doesn't work for yours ;) . Also don't forget
that win8 is there. Anyway, I would suggest to do more homework and come
up with a plausible algorithm that can be trusted to some higher level.
Maybe doing it into a PECL ext so users can rate it.

Regards

Anatol



-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to