Donate. I desperately need donations to survive due to my health

Get paid by answering surveys Click here

Click here to donate

Remote/Work from Home jobs

SpinWait — Why and how is it doing this?

Thanks for taking the time to look at my question.

I'm working on a multimedia application based mainly around .NET 4.7, DXGI, DirectX 12 and RawInput.

To summarize briefly, the application begins life as a NativeWindow with no trimmings. It initializes DirectX and RawInput according to the host hardware and starts them running on their own threads.

These are usually idle and waiting for device input except when DirectX is running in an interactive mode, which involves a fixed timestep loop and employs a timer which is also running on it's own thread.

While working on some Wacom tablet stuff in RawInput, I inserted the following code as a short delay:

Threading.SpinWait.SpinUntil(Function()                                  
      Thread.Sleep(New TimeSpan(10000))
                           Return True
                          End Function)

Half asleep, I ended up adding it to a method that is called from the DirectX thread.

That's where things got interesting.

First of all, every time the containing method was called, processor usage went down...but not the processor running the thread from which the method was called...(DirectX thread has processor affinity).

Secondly, values returned from my Timer thread became less "jittery" -- consecutive calls to QueryPerformanceCounter usually oscillated by a degree of about 8-20% but I thought this was due to the frequency at which it was being called (yielding elapsed values in the low 1000's ticks range).

A Parallel.For (6 threads) doing Verlet integration on a couple thousand geometries is suddenly able to handle about 30% more work, even though it never properly taxed the CPU to begin with (poor partitioning).

Why would calling that code-smell of a method affect other threads and other processor cores? I've checked out the SpinWait source and understand how Yield() works but calling it on it's own, or Sleep(1) as SpinWait often will, doesn't have the same effect.

Dev machine processor is an i7-8750H.

Comments