Bug #64633 [Asn]: microtime regression - resolution reduced to 64 ticks per second

From: Date: Sun, 27 Apr 2014 22:04:42 +0000
Subject: Bug #64633 [Asn]: microtime regression - resolution reduced to 64 ticks per second
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-185468@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=64633&edit=1 ID: 64633 Updated by: ab@php.net Reported by: phpbugs at musiclogistics dot net Summary: microtime regression - resolution reduced to 64 ticks per second Status: Assigned Type: Bug Package: Date/time related Operating System: Windows 7 PHP Version: 5.4.14 Assigned To: pajoye Block user comment: N Private report: N New Comment: For those interested in the usage of performance counters - please try this http://php.net/hrtime . Firstly, it is anyway interesting to see how it competes to the classic microtime() on your machine. Secondly - the performance counter API is exposed to the user space there, so it is even possible to implement some custom timing, too. Please remember though, that hrtime has nothing to do with timestamps synchronizable to an external source. Thanks. Previous Comments: ------------------------------------------------------------------------ [2014-02-10 16:20:23] ab@php.net Related To: Bug #65626 ------------------------------------------------------------------------ [2014-01-10 08:24:17] ab@php.net @louis, that's exactly what i'm talking about - with the current variant one would never get time1 > time2, i bet with the old variant using performance counters it could easy happen in your situation. Running chrome seems to be a catalyser for some instability in your case. In the current implementation time1 = time2 is the worst case, earlier it could be casual time1 > time2, or not. Now it's never time1 > time2, but with the trade off. @yohgaki, i don't think the patch you've posted is responsible, but merely the exclusion of the performance counters. On win8 one can profit from the new API call GetSystemTimePreciseAsFileTime(), which is comparable to Linux. On earlier it's GetSystemTimeAsFileTime(). The latter has poorer accuracy, but is stable and will never deliver time1 > time2. That's the trade off, as i've said above. Earlier performance counters was used instead of GetSystemTimeAsFileTime(), which led to even more confusing bugs, as in the bug #64370 and related. Turning back the old code will turn back time1 > time2 on win8 ancestors, as it's hardware+API dependent and is more random than now. ------------------------------------------------------------------------ [2014-01-08 14:13:19] louis at stovesonline dot co dot uk Having the same issue with 5.5.7 on Windows Server 2008 R2. Interestingly starting Google Chrome on the server increases the tick rate for a few seconds, meaning I can briefly get accurate results from my timing functions! ------------------------------------------------------------------------ [2013-08-01 06:53:57] yohgaki@php.net Anyone could verify that this wouldn't happen with Windows 8/Windows Server 2012? It seems different API is used for these platforms. ------------------------------------------------------------------------ [2013-08-01 06:07:53] yohgaki@php.net I guess this commit is the cause. git show b022e54bd100a914417e216 commit b022e54bd100a914417e216d0872d3e67edecaf9 Author: Anatol Belski <ab@php.net> Date: Sat Mar 23 17:40:06 2013 +0100 Fixed possible precision loss in microtime This is related to the fix for bug #64370. MSVC natively supports __int64 type, so calculating with 32 bit ints is neither necessary nor reliable. Therefore an older piece of code is reused. diff --git a/win32/time.c b/win32/time.c index 77e4504..7553974 100644 --- a/win32/time.c +++ b/win32/time.c @@ -50,6 +50,7 @@ int getfilesystemtime(struct timeval *tv) FILETIME ft; unsigned __int64 ff = 0; MyGetSystemTimeAsFileTime timefunc; + ULARGE_INTEGER fft; timefunc = get_time_func(); if (timefunc) { @@ -58,14 +59,20 @@ int getfilesystemtime(struct timeval *tv) GetSystemTimeAsFileTime(&ft); } - ff |= ft.dwHighDateTime; - ff <<= 32; - ff |= ft.dwLowDateTime; - ff /= 10; /* convert to microseconds */ + /* + * Do not cast a pointer to a FILETIME structure to either a + * ULARGE_INTEGER* or __int64* value because it can cause alignment faults on 64-bit Windows. + * via http://technet.microsoft.com/en- us/library/ms724284(v=vs.85).aspx + */ + fft.HighPart = ft.dwHighDateTime; + fft.LowPart = ft.dwLowDateTime; + ff = fft.QuadPart; + + ff /= 10Ui64; /* convert to microseconds */ ff -= 11644473600000000Ui64; /* convert to unix epoch */ - tv->tv_sec = (long)(ff / 1000000UL); - tv->tv_usec = (long)(ff % 1000000UL); + tv->tv_sec = (long)(ff / 1000000Ui64); + tv->tv_usec = (long)(ff % 1000000Ui64); return 0; } ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at https://bugs.php.net/bug.php?id=64633 -- Edit this bug report at https://bugs.php.net/bug.php?id=64633&edit=1

« previous php.bugs (#185468) next »