I/O Priorities

  • Critical
    For paging operations only
  • High
    Win7
  • Normal
    Baseline
  • Low
    Win7
  • Very Low
    Background

Windows Process I/O Priorities

Process Priority ClassI/O Priority
Real TimeCritical (for paging operations ONLY)
HighHigh*
Above NormalNormal
NormalNormal
Below NormalLow*
IdleVery Low

* = Windows 7+ only (NT 6.1)

A more *accurate* chart would show the thread CPU priority mappings to I/O priorities, but I have not yet had a chance to publish such.

More on Windows I/O Priority


Disk or network I/O usually being the bottleneck these days, the announcement of I/O prioritization in Windows Vista and above was widely applauded. Unfortunately, it isn't fully in use yet. As you'll see, there are only two application usable levels - Normal and Very Low. The way Microsoft recommends you change your I/O priority is by simply setting your priority class to Idle, as the I/O priority is derived from the calling thread's priority unless otherwise specified.

Oh goodie!

The Microsoft provided way is to specify a 'background mode' begin/end priority class to the SetProcessPriorityClass and/or SetThreadPriority API. However, these can not be set for external (other) processes, only the current, calling process can set this mode. This lets the OS control all priorities, setting to an appropriate 'background' (very low) I/O priority and an Idle CPU priority.

Note there is also a separate but related feature added to the new Multimedia Scheduler - Bandwidth Reservation. This feature attempts to guarantee I/O availability for playback in Windows Media Player or other programs that register themselves with the Multimedia Scheduler. This is what you should do if you need reliable bandwidth streaming in.

So you want to change the I/O priority

Aside from using the documented 'background mode' priority class for SetPriorityClass, you can manually tweak the I/O priority of a running process via the NT Native APIs.

Retrieving the process I/O priority is simple. If you are familiar with the NT Native API, then it will take about 10 seconds to get. If not, then familiarize yourself with the NT Native API and you'll see how easy it is. I'm not going to waste my time writing yet another book on the NT Native API. If you know how to call any API, you can call these APIs. There is documentation on the web about them, and the below paragraph will summarize their usage in setting and retrieving I/O priorities.

NtQueryInformationProcess and NtSetInformationProcess are the NT Native APIs to get and set different classes of process information, respectively. For retrieval, you simply specify the type (class) of information, and the size of your input buffer. It returns the requested information or the needed size of the buffer to get that information. The Set function works similarly, except you know the size of data you are passing to it. In the case of I/O priorities it is a ULONG, so the input and output buffer is always that same size. Therefore, the usual NT Native API duplicitous retrieval call to get appropriate buffer size isn't needed, as it is always sizeof(ULONG).

Anyway, the I/O priority is simply a new type of process information, called a 'class' (bad name I always thought, though technically accurate the layman may confuse it with some C++ class object). Added in the Windows 2008 DDK, it is defined in the enum PROCESS_INFORMATION_CLASS::IoPriority.

I could give you some example code, but if you know the NT native API you'll know exactly what I mean and have it implemented before reading the second paragraph. If not, then read up on the NT Native API and then you can implement it.

DRAFT

This article is part of a collection of information available at Bitsum Technologies as part of our Process Lasso software. As we do our own research, we publish it for the assistance of the greater community, and to make our competitors job's easier (lol).

Process Lasso (not yet another task manager) can directly set the I/O priority of a process, either permanently (every time run) or only for the current instance. It also has always had the ability to indirectly set the I/O priority via its ProBalance algorithm. If I/O is an issue, it is recommended you set ProBalance to use Idle instead of Below Normal. This may work better, but you won't know until you try it on your particular system. Each system is different, having a different software and hardware environment

For previous versions, simply setting the process priority class to Idle will suffice to lowering its priority level.

Reminder about what CPU % use is

I want to remind people that CPU utilization occurs in micro-bursts, and the % use per second is not a perfect representation of how fast or slow a CPU is. That is to say, just because that metric shows only 75% of a CPU consumed, that doesn't mean that you had an "extra" 25% laying around. The speed at which that 75% was executed matters too. At best this metric gives you some idea of how CPU intensive your operations are.

NO gimmicks!