SwitchToThread/Thread.Yield vs. Thread.Sleep(0) vs. Thead.Sleep(1)

后端 未结 4 1435
-上瘾入骨i
-上瘾入骨i 2020-12-13 04:25

I am trying to write the ultimate \"Yield\" method to yield the current time slice to other threads. So far I have found that there are several different ways to make the th

4条回答
  •  伪装坚强ぢ
    2020-12-13 04:51

    In addition to other answers, here are some profiling numbers.

    (!) Don't take this profiling too seriously! Is made just to illustrate above answers in numbers and roughly compare magnitude of values.

    static void Profile(Action func)
        {
            var sw = new Stopwatch();
            var beginTime = DateTime.Now;
            ulong count = 0;
            while (DateTime.Now.Subtract(beginTime).TotalSeconds < 5)
            {
                sw.Start();
                func();
                sw.Stop();
                count++;
            }
            Console.WriteLine($"Made {count} iterations in ~5s. Total sleep time {sw.ElapsedMilliseconds}[ms]. Mean time = {sw.ElapsedMilliseconds/(double) count} [ms]");
        }
    
            Profile(()=>Thread.Sleep(0));
            Profile(()=>Thread.Sleep(1));
            Profile(()=>Thread.Yield());
            Profile(()=>Thread.SpinWait(1));
    

    The results of spinning loops for ~5s:

    Function   | CPU % | Iters made |  Total sleep  | Invoke 
               |       |            |  time [ms]    | time [ms]
    ===================================================================== 
    Sleep(0)   | 100 0 | 2318103    | 482           | 0.00020
    Sleep(1)   |  6  0 | 4586       | 5456          | 1.08971 
    Yield()    | 100 0 | 2495220    | 364           | 0.00010
    SpinWait(1)| 100 0 | 2668745    | 81            | 0.00003
    

    Made with Mono 4.2.3 x86_64

提交回复
热议问题