Boost logo

Boost :

From: Anthony Williams (anthony_w.geo_at_[hidden])
Date: 2008-02-09 15:31:55


Howard Hinnant <hinnant <at> twcny.rr.com> writes:

> On Feb 8, 2008, at 2:42 PM, Anthony Williams wrote:
>
> > Howard Hinnant <hinnant <at> twcny.rr.com> writes:
> >
> >> template <class L1, class L2>
> >> void
> >> lock(L1& l1, L2& l2)
> >> {
> >> while (true)
> >> {
> >> {
> >> unique_lock<L1> __u1(l1);
> >> if (l2.try_lock())
> >> {
> >> __u1.release();
> >> break;
> >> }
> >> }
> >> std::this_thread::yield();
> >
> >
> > snipped rest of multi-lock code.
> >
> >> 3. The yields are absolutely necessary to get the high performance
> >> mentioned in the previous note.
> >
> > I find this comment intriguing. Is this always the case, or does it
> > depend on
> > the specifics of how a mutex is implemented on a given platform?

Thanks for the detailed experience report.

> I hope this gives you some insights, despite the lack of a clear
> answer to your question. Perhaps you or others can present a good
> explanation for this behavior regarding the yields.

I have a hypothesis about the cause for this behaviour, which is why I asked
about trials with various mutexes. My hypothesis is this: if a thread finds a
mutex locked (in try_lock), and then immediately does a lock() on that mutex, it
will probably still find it locked, and then switch to kernel mode for a
blocking wait. A yield between the try_lock() and the lock() will increase the
time before the lock() call, and thus increase the chances that the mutex
becomes unlocked, particularly if the lock is only held for a short time.

Some mutex implementations spin in user mode before switching to kernel mode for
a blocking wait, and I can even see the potential benefits of doing the
equivalent of try_lock()/yield()/try_lock()/kernel_lock() internally within the
mutex. Such mutexes might not benefit from the yield() in the generic lock()
template.

Do you still have your test code? If so, then I might run a yield/no-yield test
with a CRITICAL_SECTION based implementation, a kernel Mutex based
implementation, my boost 1.35 atomics/semaphore based mutex and a
try/yield/try/block based mutex to see if this makes any difference.

Anthony


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk