17

Please explain why Busy Waiting is generally frowned upon whereas Spinning is often seen as okay. As far as I can tell, they both loop infinitely until some condition is met.

wallyk
  • 53,902
  • 14
  • 79
  • 135
PMcK
  • 335
  • 2
  • 10

2 Answers2

11

A spin-lock is usually used when there is low contention for the resource and the CPU will therefore only make a few iterations before it can move on to do productive work. However, library implementations of locking functionality often use a spin-lock followed by a regular lock. The regular lock is used if the resource cannot be acquired in a reasonable time-frame. This is done to reduce the overhead with context switches in settings where locks usually are quickly obtained.

The term busy-waiting tends to mean that you are willing to spin and wait for a change in a hardware register or a memory location. The term does not necessarily mean locking, but it does imply waiting in a tight loop, repeatedly probing for a change.

You may want to use busy-waiting in order to detect some kind of change in the environment that you want to respond to immediately. So a spin-lock is implemented using busy-waiting. Busy-waiting is useful in any situation where a very low latency response is more important than wasting CPU cycles (like in some types of embedded programming).

Related to this are the terms «lock-free» and «wait-free»:

So-called lock-free algorithms tend to use tight busy-waiting with a CAS instruction, but the contention is in ordinary situations so low that the CPU usually have to iterate only a few times.

So-called wait-free algorithms don't do any busy-waiting at all.

(Please note that «lock-free» and «wait-free» is used slightly differently in academic contexts, see Wikipedia's article on Non-blocking algorithms.)

  • +1 in general, but a bit of nitpicking: classical CAS pattern (read-CAS-var-calculate-new-value-try-CAS-if-failed-rinse-and-repeat) doesn't really qualify as busy-waiting (we're not really waiting for some external variable _to_change_ - which can take a loooong while, but rather we are waiting for the var to be stable from external interference - which never ever takes more than 2-3 iterations in practice); still - such CAS patterns don't qualify as "wait-free" :-(. – No-Bugs Hare Sep 02 '17 at 06:22
-2

When you understand the precise reason for a rule and have detailed platform and application knowledge, you know when it's appropriate to violate that rule. Spinlocks are implemented by experts who have a complete understanding of the platform they're developing on and the intended applications for spinlocks.

The problems with busy waiting are numerous, but on most platforms, there are solutions for them. Issues include:

  1. For CPUs with hyper-threading, a busy-waiting thread can starve another thread in the same physical core, even the very thread it's waiting for.
  2. When you busy wait, when you finally do get the resource you're waiting for, you take the mother of all mispredicted branches.
  3. Busy waiting interferes with CPU power management.
  4. Busy waiting can saturate inter-core buses as the thing you keep checking causes cache synchronization traffic.

But the people who design spinlocks understand all these issues and know precisely how to mitigate them on the platform. They don't write naive spinning code, they write intelligent spinning code.

So yes, they both loop infinitely until some condition is met, but they loop differently.

David Schwartz
  • 166,415
  • 16
  • 184
  • 259