Home > Back-end >  Threading.SpinWait struct vs Thread.SpinWait method
Threading.SpinWait struct vs Thread.SpinWait method

Time:11-15

I was wondering if there was any difference between the Threading.Thread.SpinWait method and the Threading.SpinWait struct.

In particular, what would be the idiomatic way to implement a spinwait in an application :

Thread.SpinWait(1);

or

SpinWait spinWait = new SpinWait();
// ...
spinWait.SpinOnce();

CodePudding user response:

Turns out the documentation of the SpinWait struct recommends not using the Thread.SpinWait() method directly. The correct way is :

SpinWait spinWait = new SpinWait();
// ...
spinWait.SpinOnce();

SpinWait encapsulates common spinning logic. On single-processor machines, yields are always used instead of busy waits, and on computers with Intel processors employing Hyper-Threading technology, it helps to prevent hardware thread starvation. SpinWait encapsulates a good mixture of spinning and true yielding.

SpinWait is a value type, which means that low-level code can utilize SpinWait without fear of unnecessary allocation overheads. SpinWait is not generally useful for ordinary applications. In most cases, you should use the synchronization classes provided by the .NET Framework, such as Monitor. For most purposes where spin waiting is required, however, the SpinWait type should be preferred over the Thread.SpinWait method.

http://www.albahari.com/threading/part5.aspx#_SpinLock_and_SpinWait adds some details :

In its current implementation, SpinWait performs CPU-intensive spinning for 10 iterations before yielding. However, it doesn’t return to the caller immediately after each of those cycles: instead, it calls Thread.SpinWait to spin via the CLR (and ultimately the operating system) for a set time period. This time period is initially a few tens of nanoseconds, but doubles with each iteration until the 10 iterations are up. This ensures some predictability in the total time spent in the CPU-intensive spinning phase, which the CLR and operating system can tune according to conditions. Typically, it’s in the few-tens-of-microseconds region — small, but more than the cost of a context switch. On a single-core machine, SpinWait yields on every iteration. You can test whether SpinWait will yield on the next spin via the property NextSpinWillYield. If a SpinWait remains in “spin-yielding” mode for long enough (maybe 20 cycles) it will periodically sleep for a few milliseconds to further save resources and help other threads progress.

In short, as i understand it, Threading.Thread.SpinWait does the actual spinning, and Threading.SpinWait encapsulates it so that it works well in almost all cases.

  • Related