Re:No nuances, just buggy code (was: related to Spinlock imp...
by YZF on Sunday January 05, 2020 @02:03PM
(#21963159)
Do you have a reference for this? AFAIK the win32 critical section (like any modern mutex implementation) first uses atomic instructions to check if anyone is already in the critical section so it's really fast if no one is, and otherwise falls back to the OS synchronization objects.
Re:No nuances, just buggy code (was: related to Spinlock imp...
by gmueckl on Sunday January 05, 2020 @02:54PM
(#21963578)
The information is right there in the documentation:
https://docs.microsoft.com/en-us/windows/win32/sync/critical...
The paragraph about InitializeCriticalSectionAndSpinCount and SetCriticalSectionSpinCount describe the behavior. IIRC, the default spin count used to be pretty high (1000 loops or so). Not sure if that was changed.
Re:No nuances, just buggy code (was: related to Spinlock imp...
by YZF on Sunday January 05, 2020 @08:19PM
(#21965634)
Interesting. There's also that anecdote about the heap manager using a spin count of 4000. I wasn't aware this happened by default (I didn't see any mention of this in InitializeCriticalSection). I guess it's all down to the probability of contention vs. the amount of time the mutex is held.
Re:No nuances, just buggy code (was: related to Spinlock imp...
by pizlonator on Sunday January 05, 2020 @02:10PM
(#21963206)
Your description and their description are not mutually exclusive.
Re:No nuances, just buggy code (was: related to Spinlock imp...
by YZF on Sunday January 05, 2020 @08:19PM
(#21965639)
Spinning vs. a single check...
Re:No nuances, just buggy code (was: related to Spinlock imp...
by pizlonator on Sunday January 05, 2020 @01:02PM
(#21962745)
I don’t have as much experience with the Win32 scheduler. But I remember getting conflicting data about the profitability of yielding. In particular, lots of threads yielding on Win32 can cost you a lot of overall system perf, if I remember right. Not so on Linux or Darwin, on the same workloads.
It would be interesting to see a distribution of wait time per lock for different locks. If such a two step approach performs well, a hypothesis might be that there are three kinds of locks:
- mostly uncontended: lock succeeds without spinning
- held for exceptionally short amounts of time: lock usually gets released again before waiting thread on different CPU stops spinning. Wait time is lower than the time it takes to yield to the scheduler and/or reschedule.
- held for a really long time: wait time is much longer than scheduling another thread and re-scheduling the initial one.
And what you are saying seems to indicate that optimizing for the first and second one is worth it because the overhead is negligible for the third type, that is, there are few locks that are held for an amount of time so that spinning adds noticable overhead.