Why does Monitor.PulseAll result in a “stepping stair” latency pattern in signaled threads?

One difference between these version is that in PulseAll case – the threads immediately repeat the loop, locking the object again.

You have 12 cores, so 12 threads are running, execute the loop, and enter the loop again, locking the object (one after another) and then entering wait state. All that time the other threads wait. In ManualEvent case you have two events, so threads don’t immediately repeat the loop, but gets blocked on ARES events instead – this allows other threads to take lock ownership faster.

I’ve simulated similar behavior in PulseAll by adding sleep at the end of the loop in ReadLastTimestampAndPublish. This lets other thread to lock syncObj faster and seem to improve the numbers I’m getting from the program.

static void ReadLastTimestampAndPublish()
{
    while(true)
    {
        lock(SyncObj)
        {
            Monitor.Wait(SyncObj);
        }
        IterationToTicks.Add(Tuple.Create(Iteration, s.Elapsed.Ticks - LastTimestamp));
        Thread.Sleep(TimeSpan.FromMilliseconds(100));   // <===
    }
}

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)