Open Bug 1134973 Opened 9 years ago Updated 2 years ago

Use native high-resolution wait mechanisms for futexWait where possible

Categories

(Core :: JavaScript Engine, defect, P3)

defect

Tracking

()

People

(Reporter: lth, Unassigned)

References

(Blocks 1 open bug)

Details

Our portable condition variables have millisecond wait resolution (Mozilla  interval timers represent time in milliseconds).  On many platforms we can probably get microsecond resolution, certainly sub-millisecond.  We should use better wait mechanisms where possible.

futexWait does not need full condition variables, either - since our futexes provide for fairness, we may be able to get by with other mechanisms, where those are cheaper.

I suppose on Linux we might be able to use the futex mechanism directly.
Furthermore, the internals of futexWait should take note of some tricks used in Synchronic.  It would be correct to spin, or nanowait, or something, for a short time to see if the word we're waiting on is changing, which it is likely to do as part of the protocol that calls futexWait.  To do that, futexWait does not even need to take the lock.  (It does that currently so that it can use a non-atomic access for that word, but it could equally use an atomic access outside the lock, and whether it's one or more...)

I mention this since adding some spinning in Synchronic's _waitForUpdate method before going into futexWait tends to boost the performance on my hot-message-passing benchmarks by several integer factors.  (It's tricky to know how long to spin for, though, and JavaScript programs will likely have different needs than C++ programs - will likely need to spin longer.  Now asm.js programs on the other hand, I don't know.)
Indeed, the JIT can be brought to bear on the problem: the (spin|nanowait)+futexWait logic can be open-coded by the JIT, and the JIT may be able to observe the kinds of spin|nanowait durations that would be appropriate, if any at all.  This kind of structure for futexWait might in turn reduce the need for hiding wait cleverness inside Synchronic.  It would benefit JS, but not asm.js.

For Synchronic, the notion that the memory word will change is baked into the API, which makes the spin|nanowait logic easy.  For futexWait, we either would really want the JIT to observe behavior, or we'd want a hint that says whether a memory word update is expected or not.
Now that we can rely on modernish STL, would std::chrono::high_resolution_clock or std::chrono::steady_clock work for us? I could extend js::ConditionVariable to work with these, or alternatively we could use std::condition_variable directly (which js::ConditionVariable is a polyfill for).
Flags: needinfo?(terrence)
Flags: needinfo?(lhansen)
(In reply to Nick Fitzgerald [:fitzgen] [⏰PDT; UTC-7] from comment #3)

> Now that we can rely on modernish STL, would
> std::chrono::high_resolution_clock or std::chrono::steady_clock work for us?
> I could extend js::ConditionVariable to work with these, or alternatively we
> could use std::condition_variable directly (which js::ConditionVariable is a
> polyfill for).

I'm open to everything; I just want to ensure that if somebody uses Atomics.wait() with a submillisecond wait on a platform that could in principle support submillisecond waiting, then they get a submillisecond wait.  I also suspect that submillisecond waits are broadly supportable (I mean, that's easily a million clocks even on a phone).
Flags: needinfo?(lhansen)
Flags: needinfo?(terrence)
Blocks: 1317626
No longer blocks: shared-array-buffer
Priority: -- → P3
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.