48

I have a scheduled task which is very CPU- and IO-intensive, and takes about four hours to run (building source code, if you're curious). The task is a Powershell script which spawns various sub-processes to do its work. When I run the same process interactively from a Powershell prompt, as the same user account, it runs in about two and a half hours. The task is running on Windows Server 2008 R2.

What I want to know is why it takes so much longer to run as a scheduled task - more than an hour longer. One thing I noticed is that the task scheduler runs at Below-Normal priority, so when my task starts, it inherits the same lowered priority. However, I've updated the script to set the Powershell process priority back to Normal, and it still takes just as long.

Anybody have an idea what could be different between the two scenarios? I've ruled out differences in processor and IO load - this task is the only thing the system is used for, so there's nothing else running that could be competing for resources.

Charlie
  • 2,956
  • 2
  • 20
  • 13

7 Answers7

41

It appears that there is more than just "regular" process priority at work here. As I noted in the question, the task scheduler by default runs your task at lower than normal priority. This question on StackOverflow describes how to fix any task to run at Normal priority, but the fix still leaves one thing slightly different: memory priority. Memory priority was a new feature for Windows Vista, and is described in this Technet article. You can see memory priority using Process Explorer, which is a must-have tool for any administrator or programmer.

Anyway, even with the scheduled task priority fix, the memory priority of your task is set to 4, which is one notch below the normal setting of 5. When I manually boosted the memory priority of my task up to 5, the performance was on par with running the process interactively.

For info on boosting the priority, see my answer to a related StackOverflow question about IO priority; setting memory priority is done similarly, via NtSetInformationProcess, with PROCESS_INFORMATION_CLASS set to ProcessMemoryPriority (the value of this is 39 or 0x27). I might make a free utility that can be used to set this, if others need it and don't have access to programmer tools.

EDIT: I've gone ahead and written a free utility for querying and setting the memory priority of a task, available here. The download contains both source code and a compiled binary.

Charlie
  • 2,956
  • 2
  • 20
  • 13
  • You can see the memory priority in Process Explorer by double clicking on the executable's name, opening the "Performance" tab, and under "Physical Memory" is an entry for "Memory Priority" – Moshe Jul 10 '15 at 16:51
23

The issue is that your process is starting with a low I/O priority and a low memory priority. The easiest way to verify this is with process explorer from sysinternals. If you look at the properties of any of the processes that were spawned from this scheduled task, you will see that it has an I/O priority of low and memory priority of 2.

Here is the solution to this issue:

  1. Create the task
  2. Right click on the task and "export" it
  3. Edit the task.xml file that you just exported
  4. You will find a line similar to <Priority>7</Priority>
  5. Change the value to a normal priority (between 4-6). A table of the potential values: TaskSettings.Priority property
    • A value of 4 will have the same I/O and memory priority as an interactive process. Values of 5 and 6 will have lower memory priority
  6. In the task scheduler, delete the task you initially created
  7. In the task scheduler, in the actions area, import the task from the XML file

Unfortunately there is no way to modify the initial priority of scheduled tasks from the GUI.

Sean Saleh
  • 143
  • 7
Jason Mathison
  • 231
  • 2
  • 2
  • Thanks for the suggestion. Regular process priority and IO priority are definitely part of it, and the other part is memory priority. See the accepted answer for more info. – Charlie Apr 15 '11 at 18:22
  • After exporting the task to an XML file, you may need to change the character encoding from Unicode to ANSI. On Windows Server 2008 R2, the export is a Unicode file and when you try to import it back in, the error message `The format of the task is not valid. The following error was reported: (1,2)::` is given. Saving the file to ANSI resolve it for me. – Erik Anderson Dec 24 '15 at 21:55
  • Thank you very much, this is really the best solution. As the docs mention, you can also set the Priority even higher (at least up to 1), to get higher CPU priority. – Rune Aamodt May 31 '17 at 05:25
  • For anyone thinking you might be able to tweak this in the registry, don't bother, doesn't seem to be there in a nicely editable way. – Nik Dec 08 '17 at 09:40
  • This solution currently returns an error about invalid XML for some reason in Windows 10. – BIOSCMOS Dec 23 '19 at 23:03
  • @BIOSCMOS, if you didn't accidentally change the structure of the file, check the character encoding. I've read where someone else's editor saved the file in UTF-8 and changing it to ANSI saved the day. (If your favorite editor doesn't do this easily, it is easily done in Notepad-> Save as...) I know this is way late, but might help others who are still struggling with the problem. – Bob60506 Feb 25 '21 at 15:39
2

Here's a powershell snippet for setting the priority (works in a remote powershell session!):

$taskName = "MyTask" ;`
$currentTask = Get-ScheduledTask -TaskName $taskName ;`
$settings = $currentTask.Settings ;`
$settings.Priority = 4 ;`
Set-ScheduledTask -TaskName $taskName -TaskPath $currentTask.TaskPath -Settings $settings
BIOSCMOS
  • 105
  • 3
Hank Killinger
  • 95
  • 1
  • 2
  • 7
1

Maybe scheduled tasks run at a lower priority by default.

Use prio to force higher priority.

David Makogon
  • 2,767
  • 1
  • 19
  • 29
mcandre
  • 168
  • 7
  • You're right that they run at lower priority, but as I mentioned, I've already accounted for that. Unless there's some priority other than process priority that I don't know about. – Charlie Jun 16 '10 at 18:31
1

If you set it to run as a scheduled task as User X, and then login as User X before it's supposed to run, it should open a window in your session when it runs, it'll be running in your session.

If you do this, does it take the longer, or shorter, period of time? I don't know what this will mean, but it may be a useful differentiator. Could there be some network access that the user account has when logged in, but not when running as a scheduled task, that needs to timeout and fail? Is the behavior different if you create a new user account and have it run as a scheduled task under that account?

Another idea: When running it as a scheduled task - now that you've fixed the priority on your script do the sub-processes all run as Normal, or Below-Normal?

mfinni
  • 35,711
  • 3
  • 50
  • 86
  • 1
    The subprocesses definitely run as Normal, as verified by procexp/taskman. I think the network thing isn't it, because it doesn't do any substantive network access, but I'll double-check that. The idea about running the task as interactive is interesting too, I'll give it a try. – Charlie Jun 16 '10 at 18:52
  • The process itself doesn't have to do any network access that you know of for this to be a problem. Read this post from Sysinternals and see how something seemingly unrelated can cause hangs/slowness. http://blogs.technet.com/b/markrussinovich/archive/2005/08/28/the-case-of-the-intermittent-and-annoying-explorer-hangs.aspx – mfinni Jun 16 '10 at 19:24
0

at first - you can use more than normal priority (High for example)

at second - you have to understand, than foreground session takes some resources, mainly hard disk IO and memory so scheduled task gets less. for clear benchmark you have to logoff while you powershell script running

and also you can try add more memory / use ramdrive / split work on several hard disk to speed up processes

evg345
  • 384
  • 1
  • 4
  • Thanks for the ideas. The machine has plenty of memory and IO capacity, the problem is just that things run slower as scheduled tasks than they do interactively. When the scheduled task is running, there is usually no interactive logon session, so I think that's not the issue either. – Charlie Jun 21 '10 at 00:57
0

This question is from a while ago, and for windows server 2008R2. I had the same question, but for Windows 10. On Windows 10 (verified on 1703 and 1809), just setting the "Priority" to 4 via imported xml is enough to give you the same Base Priority, Dynamic Priority, I/O Priority, and Memory Priority as an interactively started process.

aggieNick02
  • 266
  • 2
  • 9