Open Bug 908040 Opened 11 years ago Updated 3 days ago

performance.now() backwards ticks rarely (under 1 in 1000 user agents)

Categories

(Core :: XPCOM, defect)

24 Branch
x86
Windows 8
defect

Tracking

()

UNCONFIRMED

People

(Reporter: registerbox, Unassigned)

Details

User Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36

Steps to reproduce:

1. Read performance.now()
2. Do something
3. Read performance.now()

The value in (3) should always be monotonically bigger than (1)


Actual results:

One web visitor of my TestUFO motion test (www.testufo.com) transmitted a log entry to my server over AJAX:

Ticks:4,-109,5,4,-110,-108,4,5,119,5,4,119,4,5,-109,6,4,5,4,-110,117,3,-111,3,118,119,120,1174,820 (Firefox 24,Windows)

These are consecutive performance.now() deltas.  I have traced this to a backwards tick in performance.now that only occurs on one web visitor, running FireFox 24 on the Windows platform.   I am not sure what the full useragent was, since that was not logged with this specific information.


Expected results:

performance.now() should always monotonically tick forward.
I posted a message on W3C recently:

Regarding: http://www.w3.org/TR/hr-time/

One useful consideration about high-resolution timers (HRT) on some
platforms is that if you read a HRT from one thread, then the thread
undergoes a context-switch to a different processor core on a CPU, you may
get a few microseconds difference in the HRT.  In rare cases, you may even
get a "backwards tick".

To solve the backwards tick problem, sometimes these techniques have been
used:
(1) Use thread affinity, to read the HRT only via the same core.
(2) Compare the tick value to the previous tick, and reject the backwards
tick.  Reuse the previous tick value instead.  Resume measurements with
subsequent reads.

The HRT usually remains constantly monotonic even whenever the clock is
changed (e.g. synchronized to an Internet time server), but make sure
that's correct.  This may be a nonissue for Windows
QueryPerformanceCounter() which always increases monotonically on the same
CPU core -- but it does have the potential microsecond differences between
different cores, so you want either thread affinity or a backwards-tick
check & reject (use old value).
There is a known bug on some AMD CPU's, 
http://stackoverflow.com/questions/644510/cpu-clock-frequency-and-thus-queryperformancecounter-wrong

"QueryPerformanceCounter() and QueryPerformanceFrequency() offer a bit better resolution, but have different issues. For example in Windows XP, all AMD Athlon X2 dual core CPUs return the PC of either of the cores "randomly" (the PC sometimes jumps a bit backwards), unless you specially install AMD dual core driver package to fix the issue. We haven't noticed any other dual+ core CPUs having similar issues (p4 dual, p4 ht, core2 dual, core2 quad, phenom quad)."

FireFox should follow Microsoft KB274323 Recommendation
http://support.microsoft.com/kb/274323
Component: Untriaged → General
Product: Firefox → Core
Keywords: perf
OS: Windows 8 → All
Hardware: x86_64 → x86
We implement the recommendation from KB274323 as far as I can tell.  See TimeStampValue::CheckQPC in http://mxr.mozilla.org/mozilla-central/source/xpcom/ds/TimeStamp_windows.cpp
Component: General → XPCOM
Keywords: perf
OS: All → Windows 8
Hardware: x86 → x86_64
Hardware: x86_64 → x86
I'm going to add some more intentional AJAX logging to capture more information every time a backwards tick is detected by a visitor (full useragent logging), to isolate the specific version of Windows and specific version of FireFox.

However, backwards tick events are so rare, that I've only seen this twice in my lifetime (this year).  Debug logging might be prudent in the nightlies to detect backwards ticks, because it's such a hard-to-reproduce thing.
P.S. This likekly isn't Windows 8, but probably one of the older versions of Windows, as XP has this issue more often than Windows 8 does.  Hopefully the coming weeks should reveal more info.
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.