2

If I Wait on a Pulse from Monitor.Wait() as in the example below, does the system still schedule the waiting thread (including context switching it) and check a condition before yielding the time slice?

Or is the thread not scheduled again, and 'woken' up by the kernel when another thread calls Monitor.Pulse()?

Monitor.Enter(LOCK_OBJ);
Monitor.Wait(LOCK_OBJ);
Monitor.Exit(LOCK_OBJ);

The reason I ask, is that I want to avoid context switching unnecessarily while a thread waits for a long time. Basically, I want to 'hibernate' the thread.

Xenoprimate
  • 7,691
  • 15
  • 58
  • 95
  • Corollary question for my own curiosity: if the answer is that the scheduler polls, does that matter? I.e., is the cost of this polling in any way significant? – TypeIA Mar 15 '14 at 21:56
  • @dvnrrs I'm writing a parallelized game engine; and so I'm trying to get optimum efficiency out of it. I mean, it may all be lost in the noise of every other process's scheduling, but even so, I wouldn't mind just knowing the answer from a curiousity standpoint. – Xenoprimate Mar 15 '14 at 21:59
  • 1
    Yep, that comment wasn't meant to belittle the question, I'm curious too. I highly doubt it matters but I don't know exactly how a scheduler handles wait conditions so I'd like to learn. – TypeIA Mar 15 '14 at 22:00

1 Answers1

0

The Monitor.Wait implementation is discussed in detail in When exactly .NET Monitor goes to kernel-mode?.

If the locking time is small and the cost of kernel mode waits and context switches is too high, you should look into using a spinlock instead. Instead of yielding the CPU, a spinlock busy-loops trying to acquire the lock. The pro is that it never incurs the overhead of a context switch. The con is that it keeps the CPU busy.

For a performant game engine where there is some shared data that is locked very briefly, a spinlock is the right thing to use.

Community
  • 1
  • 1
Anders Abel
  • 67,989
  • 17
  • 150
  • 217
  • Hi Anders - thanks for the comment about the spinlock. I'm already using such an implementation in the parallel pipeline, but I want to use an additional 'worker thread' pool for latent tasks, hence my curiosity about whether they will impact the scheduling whilst suspended. – Xenoprimate Mar 15 '14 at 22:22
  • If you really want to get all performance possible out of the system, you should have as many threads as you have CPU cores and then assign work items to them off one or more queues. The latent tasks could be on a less prioritized queue that's polled when the high priority tasks are done. But then C# is the wrong language. You don't want a garbage collector if you want max performance. – Anders Abel Mar 15 '14 at 22:43
  • I have a C++ element, but also the GC is less of an issue if you create less garbage. :) – Xenoprimate Mar 15 '14 at 22:57
  • Also the modern .NET GC is very good. We successfully use C# for a soft-realtime simulation environment with > 100 Hz frames with near-C++ performance and frame jitter. – TypeIA Mar 15 '14 at 23:29