Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I/O priority of a process be increased?

I want to increase the I/O priority of a process. Answers for both .NET and Windows Vista would be nice. processexplorer is ok as well.

like image 257
yusuf Avatar asked Nov 19 '08 08:11

yusuf


People also ask

How do I increase IO priority?

Using this API you can change the I/O priority. This API accepts a 'class' variable telling it what type of information about the process you want to change, that class variable must be set to ProcessIoPriority. You can then set the entire process's I/O priority in this manner.

How do you change the priority of a running process?

You can change the scheduling priority of a running process to a value lower or higher than the base scheduling priority by using the renice command from the command line. This command changes the nice value of a process.

What is IO priority?

I/O priority queueing is used to control deferred I/O requests. If this function is invoked, all deferred I/O requests, except paging and swapping, will be queued according to the I/O priorities associated with the requesting address spaces. Paging and swapping are always handled at the highest priority.

What determines process priority?

If the nice value of a process is lower, it gets a higher priority, which means the CPU will execute that process more often. But, if the nice value of a process is higher, it will be assigned a lower priority, which means that the CPU will execute that process less often (whenever it gets an opportunity).


2 Answers

The relevant information seems to be a bit scattered compared to the usual MS documentation. There is this white paper that discusses I/O Prioritization in windows. This doc seems to have beta flags all over it but I guess it's probably mostly pretty accurate.

Two important things to note:

  1. You can only reduce the priority of IO requests below normal.
  2. The driver can ignore any such request and treat it as normal anyway.

The useful APIs for client applications are SetFileInformationByHandle:

FILE_IO_PRIORITY_HINT_INFO priorityHint;
priorityHint.PriorityHint = IoPriorityHintLow;
result = SetFileInformationByHandle( hFile,
                                     FileIoPriorityHintInfo,
                                     &priorityHint,
                                     sizeof(PriorityHint));

SetPriorityClass:

// reduce CPU, page and IO priority for the whole process
result = SetPriorityClass( GetCurrentProcess(),
                           PROCESS_MODE_BACKGROUND_BEGIN);
// do stuff
result = SetPriorityClass( GetCurrentProcess(),
                           PROCESS_MODE_BACKGROUND_END);

SetThreadPriority which is similar:

// reduce CPU, page and IO priority for the current thread
SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN);
// do stuff
SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_END);

SetFileBandwithReservation:

// reserve bandwidth of 200 bytes/sec
result = SetFileBandwidthReservation( hFile,
                                  1000,
                                  200,
                                  FALSE,
                                  &transferSize,
                                  &outstandingRequests );

For .Net do the usual stuff with P/Invoke.

like image 60
1800 INFORMATION Avatar answered Sep 24 '22 08:09

1800 INFORMATION


It looks like the "real" way to set the IO priority of a process is using NtSetInformationProcess with the ProcessIoPriority information class. Unfortunately this API is undocumented, but you can see it in action by attaching a debugger to taskeng.exe and breaking in ExeTask::GetYourPrioritiesStraight.

I believe the PROCESS_INFORMATION_CLASS value for ProcessIoPriority is 33 (0x21), and the priority values are as follows:

Very Low: 0
Low: 1
Normal: 2
High: 3 or above?

The values above are a best-guess based on what I can tell from the debugger; the task scheduler seems to use a value of 1 for tasks with priority 7, and a value of 2 for tasks with priority 5 (see this question and this MSDN article for more on task scheduler priorities). Calling SetPriorityClass with PROCESS_MODE_BACKGROUND_BEGIN uses a value of 0.

I have unfortunately not found any public API that can be used for this, other than the SetPriorityClass method in @1800 INFORMATION's answer, which sets the priority to Very Low.

Edit: I've written a utility that can be used to query or set the IO prority of a process, available here.

like image 40
Charlie Avatar answered Sep 23 '22 08:09

Charlie