Saturday, February 19, 2011

PowerShell yielding to OS in tight loops

I've previously encountered the suggestion to call System.Threading.Thread.Sleep(0); in tights loops in C# to prevent CPU hogging and used it to good effect.

I have a PowerShell script that has a tight loop and I'm wondering whether I should be calling [Thread]::Sleep(0) or Start-Sleep 0 or whether the PS engine will yield for me occasionally.

From stackoverflow
  • I would recommend to use Thread.SpinWait(20). It works well on Intel HT boxes. The advanced way is to check the number of CPU's and call either Sleep(0) for single CPU or SpitWait(20) otherwise

    Jason Stangroome : The MSDN doc on SpinWait suggests to me it isn't the right choice apart from the small warning saying it may help on Intel HT in certain situations. Hasn't HT been dropped from Intel Core CPUs? Also, why choose "20" as the argument to SpinWait?
  • I find there are a couple of problems with explicitly yielding a thread via .Sleep() or other means when you are just making sure it doesn't take over the processor. The first is that it just makes your code look poor as it's sprinkled with Thread.Sleep(0). You can comment every instance but it doesn't look great.

    The next problem is that you can only yield the code you control. This doesn't help at all if part of the long running script calls a long running function you have no control over.

    Instead I would alter the ThreadPriority during the long running operation to be BelowNormal or Lowest. This will solve both problems and likely will be more effecient as the OS can now make a more informed decision as to when to page you out.

    [Thread]::CurrentThread.ThreadPriority = System.Threading.ThreadPriority.Lowest
    

0 comments:

Post a Comment