Consequences of the scheduling algorithm: Low priority threads can take 100% CPU


I see variations on this question occasionally. "Why is my low priority thread consuming 100% CPU?"

Setting a thread to low priority doesn't mean that it won't consume lots of CPU. It just means that it doesn't get to run as long as there is a higher-priority thread ready to run. But if there is a CPU looking for something to do, and there is no higher-priority thread that is runnable, your low-priority thread will run, and if your low-priority thread is CPU-intensive, it will get all the CPU.

Priority merely controls which threads get first dibs on CPU time, but if you arrange so that your thread is the only one who wants to run, then it get all the CPU. The chicken at the bottom of the pecking order gets to eat all it wants if no higher-rank chickens are around. You paid for that CPU. There's no point withholding it just out of spite.

Comments (33)
  1. Technoid says:

    Actually on Cool & Quiet enabled cpu’s, a low prioritized thread won’t get all of the cpu since the C&Q function will throttle back the cpu to its lowest frequency.

  2. JS says:

    Technoid: I don’t think that’s the case.  C&Q (or Intel Speedstep) will throttle down the CPU if it’s idle.  Simple as that.  I doubt the CPU has any way to distinguish low-priority thread consuming 100% CPU time vs. high-priority thread doing the same.  I’m not even sure the CPU has any concept of "thread"; that’s an OS abstraction.

    <rant>Anyone else dislike how Windows essentially lets a thread of priority N starve if there’s a thread of priority N + 1 running?  If everyone made their background work threads low-priority, this would probably be fine, but too often I find I have to manually reduce an application’s priority in Task Manager in order to unfreeze another app.  IMHO, giving a priority-N+1-thread proportionally more CPU time than a priority-N thread, but letting both run, would work a lot better… probably make a single-core machine feel more like a dual-core machine, even.</rant>

  3. Huang says:

    Low priority thread says – All your cpu are belong to us.

  4. James Schend says:

    JS,

    Have you given it a try in Vista? In my experience, Vista is much more responsive in situations where XP would be basically halted. (Especially when threads are stalled waiting for I/O.)

    Of course I’m not sure what combinations of programs are doing this to you, it only happened very, very rarely to me in XP and usually it was over and done before I could get task manager opened anyway.

  5. dave says:

    JS: I think the CPU speed scaling is under the control of the OS, not the hardware, so it can make a distinction based on the priority of the process using the CPU.

    Last time I ran Linux on a laptop (Centrino SpeedStep capable), there was a runtime-settable option for whether the CPU speed control treated niced (low-priority) processes as "active" or "idle".

    My Macbook hides the details from me, but I would be surprised if it doesn’t do something similar; for both MacOS and Windows, if it doesn’t, I’m pretty sure that’s a design decision and not a hardware limitation.

  6. Sunil Joshi says:

    ‘Anyone else dislike how Windows essentially lets a thread of priority N starve if there’s a thread of priority N + 1 running?’

    I thought that the OS temporarily boosted thread priorities to ensure that this didn’t happen. According to this page, the adjusted priority is called dynanmic priority:

    http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit/prork/pred_ana_umwv.mspx?mfr=true

  7. Gabe says:

    Pretty much all process accounting mechanisms compute a process’ CPU time based on what fraction of available cycles it consumes. That means if your 2.5GHz CPU lowers its speed to 1MHz in power-save mode, your low-priority process that uses 1M cycles in 1 second will be charged with 100% of the CPU time even though it used only 0.04% of all cycles that the CPU is capable of.

  8. Dan says:

    There have been times I swear a Below Normal process has been hogging the CPU causing my Normal and above processes to hang.  Of course I’ve never been able to catch it, since it even slows down Process Explorer’s launching sequence to a crawl so by the time ProcExp has launched the rogue process has stopped eating the CPU.  It’s infuriating.

    I suppose it could be due to no I/O scheduling in XP.  Vista isn’t really an option for me because it runs too slow.

  9. anonymous says:

    Please don’t forget that the idle thread in the Idle pseudo process is a thread as well – if it rans, the CPU will switch down speed.

  10. Wesha says:

    > You paid for that CPU. There’s no point withholding it just out of spite.

    To the contrary, Microsoft conveniently forgot about that philosophy in Vista, and has no problem running software I don’t want on CPU I paid for. (Read: DRM).

    [Thank you for turning a technical argument into a political one. Allow me to rephrase. “There’s no point forcing part of it to sit idle when there’s stuff it could be doing.” -Raymond]
  11. Darrell Bennington says:

    This reminds me of one of the first multi-threading projects I worked on.  The software I was working on gave differing views of some test data off of what was basically a packet sniffer, some of the views very high level overviews that had to sift through quite a bit of data for even a screen full.  A background thread was created with low priority as soon as the file was downloaded to pre-process the info.  One of our users started complaining that the fan on her laptop would turn on when using the software with the latest version – no other problems with speed or sluggishness.  We eventually figured out that it was this background thread using all the CPU when nothing higher priority was running.

    Personally, I thought this was a good compliment to how well it worked – the only way she knew it was even running was the fans would kick on – management sided with her and the background thread turned into something that needed to be explicity launched by the user.

  12. JenK says:

    "Priority merely controls which threads get first dibs on CPU time, but if you arrange so that your thread is the only one who wants to run, then it get all the CPU. The chicken at the bottom of the pecking order gets to eat all it wants if no higher-rank chickens are around. You paid for that CPU. There’s no point withholding it just out of spite."

    I’m amazed that you’ve maintained that dry sense of humor while living in the Northwet.  

    Thanks for the laugh. :)

  13. Andrew Cook says:

    I don’t care about politics, so I’m going to skip the DRM comment. :)

    [“There’s no point forcing part of it to sit idle when there’s stuff it could be doing.” -Raymond]

    Well, there’s one point. I run a NetBurst CPU still ( P4 Prescott 3.2GHz, yeah yeah yeah I know I’m obsolete… ) and some times I want to be able to bubble the pipeline with HLT instructions for thermal management reasons. Like when my thermal compound stopped working. In order to keep the CPU from going into thermal failure I had to use WinDBG to break into all processes that wanted to spend 100% of the CPU, including the low-priority ones, to keep the proc from going from 20 degrees to thermal failure in a minute thirty flat. I did eventuallly get that fixed when an Amazon box arrived, but in the meantime…

    Granted, it’s a very nonstandard use case. But it would make sense to have such a feature in the scheduler so that in situations when the processor cannot throttle down the OS can.

    [I can see the scathing reviews already. “We kicked off a background spellcheck, and it took three times as long on Windows n+1 than on Windows n. It takes a certain type of programming genius to make something suck that much.” -Raymond]
  14. Mark Sowul says:

    Netburst had built in thermal management to throttle the clock if it was overheating.

    http://www.intel.com/cd/channel/reseller/asmo-na/eng/support/support_faq/tech/242783.htm

    (Among many other references – Tom’s hardware had a video of it in action.  They removed the CPU cooler entirely while playing a game.  The Pentium 4 would slow down, the Pentium III would lock up, and the Athlon XPs went up in smoke.)

  15. Jimbo says:

    Before people complain about thread scheduling in Win32, be sure you’re read up on dynamic thread priority adjustments and how the run queue works.  Remember that the kernel threads to page memory in and out from the pagefile have a higher priority than most processes — thus, a low-level process may need a lot of pages from disk, and higher-priority threads are blocked during the access.  And, learn the difference between an I/O-bound thread and a CPU-bound thread.  Win32’s scheduling algorithm makes a lot more sense when you understand all the issues it’s attempting to solve.

  16. Hobie-wan says:

    I remember similiar confusion in a thread about games and upgrading PCs a few years ago before video cards were handling much of the polygonal calculation. Some person was complaining that 3D game X was always consuming 100% of their processor, so they bit the bullet and upgraded their processor. They were complaining that it still took 100% of their processor, thinking that it should only take say 66% since it was 1 1/2 times faster. They couldn’t seem to grasp that the processor was always going to peg at 100% to give them the smoothest experience possible.

  17. TraumaPony says:

    It could be worse; it could be in an infinte loop :P

  18. James Day says:

    Darrell, your background process could have been set to a default cap of say 10% of CPU use, controlled by the application. So 100% CPU available, still uses 10% max and the fan never starts. Also a good idea to check whether the computer is on battery power and do no work if it is.

  19. James Day says:

    Hobie-wan, the game designers should appreciate that the user wanted them to not use all of the CPU for the game and went so far as to spend lots of money to try to achieve that result. The user might have other tasks to run or might prefer a quiet computer with temperature-controlled fans not running at full speed and annoying other family members, say.

  20. SuperKoko says:

    "Hobie-wan, the game designers should appreciate that the user wanted them to not use all of the CPU for the game and went so far as to spend lots of money to try to achieve that result."

    Providing a max-fps setting makes sense.

    It’s not good to have an old game running at 3000 fps and eating 50% of your CPU while you’ve background tasks (compressing files or other tasks). If max-fps could be set to 120, the game would still be perfectly smooth, but would eat less than 2% of the CPU, giving more CPU time to other threads.

    I don’t even count those un-cooperative fixed frame-rate games spending their sleeping time in empty loops eating as much CPU as they can.

    Even if Windows is a pre-emptive multitasking OS, some level of cooperation can improve system performances.

    However, I guess that this specific game wasn’t "old" and so could really run smoother thanks to the new CPU. Going from 30 fps to 50 fps is a Good Thing(TM).

    PS: I find it funny that there are people who look at the system monitor and cry whenever more than 50% of their RAM or CPU is eaten. Some of them wish that there were an OS option to limit the amount of RAM and CPU taken to 50% of the available amount (slowing down their entire system).

  21. Igor Levicki says:

    The real tragedy is that the majority of programs use 100% of your CPU *INEFFICIENTLY*.

  22. neerajsi says:

    @Gabe:

    I believe it’s much more complicated than that in Windows and it’s one of those nasty intersections of changing hardware and software behaviors.  Until Vista there was no cycle-based CPU accounting, so I believe it was done off of the clock tick counter (10 ms granularity), but I’m not absolutely sure.

    Now there is cycle counting, but some CPUs change the rate of cycle counting depending on the power state of the processor, and it’s simply not worth the hassle of keeping track of the current value per-processor in a synchronized manner.  To make a long story short, the scenario you’re talking about (100% cpu but throttled down) probably can’t actually happen and wouldn’t be displayed that way.  

    Newer processors actually may actually promise to keep the timestamp counter running at its nominal speed regardless of CPU power state.  

  23. Neil says:

    Won’t your low priority thread tend to increase its working set at the expense of swapping out all your waiting high-priority threads, which then have to wait even longer so that they can be swapped back in again?

  24. Andrew Cook says:

    [I can see the scathing reviews already. “We kicked off a background spellcheck, and it took three times as long on Windows n+1 than on Windows n. It takes a certain type of programming genius to make something suck that much.” -Raymond]

    Good point. Kernel flag off by default then?

    @Mark:

    I have a 540J, which supports HT technology and PAE/NX, but not EM64T nor SpeedStep.

    [Seems awful strange to spend all that effort to add a scheduler feature only to leave it off by default. -Raymond]
  25. Triangle says:

    [I can see the scathing reviews already. "We kicked off a background spellcheck, and it took three times as long on Windows n+1 than on Windows n. It takes a certain type of programming genius to make something suck that much." -Raymond]

    Searching for something is memory bound, not a CPU bound. The CPU would be idle for half of its cycles anyway waiting for data from RAM.

    "Remember that the kernel threads to page memory in and out from the pagefile have a higher priority than most processes — thus, a low-level process may need a lot of pages from disk, and higher-priority threads are blocked during the access."

    Isn’t the I/O scheduler in Vista supposed to fix precisely this kind of problem ? Also, if threads are blocked because of disk access, it’s accessing the disk synchronously, which no OS on earth does anymore.

  26. Cooney says:

    [I can see the scathing reviews already. "We kicked off a background spellcheck, and it took three times as long on Windows n+1 than on Windows n. It takes a certain type of programming genius to make something suck that much." -Raymond]

    beats burnmarks on my thighs. Of course I’m some sort of freak – I want a laptop that lasts a long time, has a decent screen, etc, but doesn’t need to be all that fast.

  27. idler says:

    Is it even possible for software to throttle back the cpu when executing instructions? I supposed that the cpu didn’t throttle back when executing instructions other than hlt.

    The scheduler could maybe interleave the instructions from the low priority thread with hlts somehow, or maybe executing the thread every other second, but I guess that would not be easy or compatible.

  28. Cooney says:

    Is it even possible for software to throttle back the cpu when executing instructions? I supposed that the cpu didn’t throttle back when executing instructions other than hlt.

    Sure – that’s how clock scaling works.

  29. Igor Levicki says:

    Seems awful strange to spend all that effort to add a scheduler feature only to leave it off by default.

    Isn’t that how majority of Windows features work? :)

  30. Hobie-wan says:

    "However, I guess that this specific game wasn’t "old" and so could really run smoother thanks to the new CPU. Going from 30 fps to 50 fps is a Good Thing(TM)."

    Exactly. This was around Quake 1 and Half-Life 1.   So it also meant Windows 98, some people still doing software rendering, and trying to crunch numbers while you gamed wasn’t a Good Thing®.

  31. Jimbo says:

    "Isn’t the I/O scheduler in Vista supposed to fix precisely this kind of problem ? Also, if threads are blocked because of disk access, it’s accessing the disk synchronously, which no OS on earth does anymore."

    I don’t know Vista well enough to comment on that.

    I wasn’t saying there was synchronous I/O.  The threads that are blocked are the normal priority threads, which are higher than the low-priority thread causing the demand paging, but lower than the kernel threads actually fetching the page.

    A low-priority thread could inadvertantly demand a page in.  Or, imagine the thread demanding hundreds of pages in (or out!)  The CPU time the high-priority kernel threads needed to read/write from the disk would block even a normal-priority thread.  If it was synchrounous I/O, yes, that would be numbskull, but then the kernel threads would block more often, relinquishing control more often.  But because they work on non-blocking I/O, that means they’re going to stay *busier* manipulating pages — keeping lower priority threads on the pending queue.

    We’re not talking hours of wait time here, only that the NT architecture has this sort of behavior, and it seems a bit perverse at first blush.

  32. - says:

    The thing is still broken in Vista. There are a few unrelated changes, but it basically works the same.

    The right way to do it is to dynamically lower the priority of the threads that are hogging the CPU.

    The way Windows does it doesn’t make sense, and "feels" much worse in terms of responsiveness the moment there’s CPU pressure.

    I/O scheduling has nothing to do with this. If a thread gets blocked for I/O, another thread can be executed immediately on the CPU. That’s certainly not new in Vista. I/O scheduling just lets you prioritize I/O requests.

Comments are closed.

Skip to main content