Microsoft's apparent plan was to adjust I/O priorities in relative alignment with the calling thread's CPU priority. This makes it an easy plug-in to the OS that has good backwards compatibility. It may also be the case that the two should be kept in sync under many circumstances. What we know for sure is that Microsoft provided no high-level (e.g. kernel32.dll) API to directly set process I/O priorities, nor did it document them well at all. It *does* provide an NT native API, but as with all those APIs, the documentation is incomplete or missing, and they are subject to change without notice. In other words, they aren't really intended for developers to use. So, we presume from this Microsoft deters developers from changing their own I/O priority, and instead recommends they set their process priority class accordingly.
Below is the conversion chart for these automatic mappings. For details on how to change a process I/O priority, jump on below. It is really simple, especially if you've used the NT native API before. These may not apply for every application, particularly if it sets its own thread priorities.
|Process Priority Class||I/O Priority|
|Real Time||Critical (for paging operations ONLY)|
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.
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.
Far too little has been published on the technical specifications of the I/O priotization that Microsoft added to Windows Vista and above. This short article does not dive too deeply into them, but does inform the reader how to set your own I/O priority directly while maintaining a separate CPU priority. I'm sure somewhere there is a good reason to do this, but be sure to ask yourself if you really want to before you do.
After hearing of I/O priorities the first question you may ask (if you're a developer) is "How do I change my application's I/O priority?" Well, as I've always said, the I/O priority is derived from the calling thread's priority. Therefore, Microsoft recommends applications set their I/O priority indirectly by changing either the base process priority class or individual thread priority. In this manner, Process Lasso and its ProBalance has always done I/O prioritization through this, recommended, route.
This is why Microsoft provided no documented 'official' method of directly changing the I/O priority. They wanted it derived from the thread priority, making it a 'drop in' addition to Windows. Processes running at Idle get Low priority I/O.
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.
For one reason or another you want your CPU priority to be different than your I/O priority. Ok, great. Fortunately there is a way to do this from user mode. However, you can only do it with the undocumented NT native APIs. In the case of Process Lasso that already utilizes these NT native APIs, adding support was a breeze. The only bad thing about the NT Native APIs is that they are not guaranteed not to change (unlike other Windows APIs). However, Microsoft rarely changes them, and when they do, backwards compatibility is usually maintained. Still, you must stay 'on top of your game' to make sure you keep up with the latest service packs in case anything does change.
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.
(c)2010,2011,2012 Jeremy Collake
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).
Get Process Lasso to experience the benefits of automated process priority adjustment and more.
Process Lasso 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.