El proceso se ejecuta más lentamente como una tarea programada que interactivamente

41

Tengo una tarea programada que es muy intensiva en CPU e IO, y toma alrededor de cuatro horas en ejecutarse (compilando el código fuente, si tiene curiosidad). La tarea es un script de Powershell que genera varios subprocesos para hacer su trabajo. Cuando ejecuto el mismo proceso de manera interactiva desde un indicador de Powershell, como la misma cuenta de usuario, se ejecuta en aproximadamente dos horas y media. La tarea se ejecuta en Windows Server 2008 R2.

Lo que quiero saber es por qué tarda tanto más en ejecutarse como una tarea programada, más de una hora más. Una cosa que noté es que el programador de tareas se ejecuta con una prioridad por debajo de lo normal, por lo que cuando se inicia mi tarea, hereda la misma prioridad reducida. Sin embargo, he actualizado la secuencia de comandos para volver a establecer la prioridad del proceso Powershell en Normal, y todavía me lleva el mismo tiempo.

¿Alguien tiene una idea de lo que podría ser diferente entre los dos escenarios? He descartado las diferencias en el procesador y la carga de E / S: esta tarea es lo único para lo que se usa el sistema, por lo que no hay nada más en ejecución que pueda competir por los recursos.

Charlie
fuente
¿Alguna actualización? Tengo mucha curiosidad por ver qué puedes encontrar.
mfinni
Encontré lo que creo que fue la causa; mira mi respuesta a continuación.
Charlie
A partir de Windows 10 Fall Creators, este problema aún existe y la solución alternativa de @Jason Mathison (editar el archivo .xml del Programador de tareas) sigue siendo la mejor solución.
BSalita

Respuestas:

36

Parece que aquí hay más que solo una prioridad de proceso "regular" en el trabajo. Como señalé en la pregunta, el programador de tareas por defecto ejecuta su tarea con una prioridad inferior a la normal. Esta pregunta en StackOverflow describe cómo arreglar cualquier tarea para que se ejecute con prioridad Normal, pero la solución aún deja una cosa ligeramente diferente: prioridad de memoria. La prioridad de memoria era una nueva característica para Windows Vista y se describe en este artículo de Technet . Puede ver la prioridad de memoria con Process Explorer , que es una herramienta imprescindible para cualquier administrador o programador.

De todos modos, incluso con la corrección de prioridad de tarea programada, la prioridad de memoria de su tarea se establece en 4, que es una muesca por debajo de la configuración normal de 5. Cuando aumenté manualmente la prioridad de memoria de mi tarea hasta 5, el rendimiento estaba en a la par con ejecutar el proceso de forma interactiva.

Para obtener información sobre cómo aumentar la prioridad, consulte mi respuesta a una pregunta relacionada de StackOverflow sobre la prioridad de E / S; La configuración de la prioridad de la memoria se realiza de manera similar, a través de NtSetInformationProcess, con PROCESS_INFORMATION_CLASSset to ProcessMemoryPriority(el valor de esto es 39 o 0x27). Podría hacer una utilidad gratuita que pueda usarse para configurar esto, si otros lo necesitan y no tienen acceso a las herramientas del programador.

EDITAR: He seguido adelante y escribí una utilidad gratuita para consultar y establecer la prioridad de memoria de una tarea, disponible aquí . La descarga contiene tanto código fuente como un binario compilado.

Charlie
fuente
Puede ver la prioridad de memoria en Process Explorer haciendo doble clic en el nombre del ejecutable, abriendo la pestaña "Rendimiento", y debajo de "Memoria física" hay una entrada para "Prioridad de memoria"
Moshe
17

El problema es que su proceso comienza con una prioridad de E / S baja y una prioridad de memoria baja. La forma más fácil de verificar esto es con el explorador de procesos de sysinternals. Si observa las propiedades de cualquiera de los procesos que se generaron a partir de esta tarea programada, verá que tiene una prioridad de E / S baja y una prioridad de memoria de 2.

Aquí está la solución a este problema:

  1. Crea la tarea
  2. Haga clic derecho en la tarea y "exporte"
  3. Edite el archivo task.xml que acaba de exportar
  4. Encontrará una línea similar a <Priority>7</Priority>
  5. Cambie el valor a una prioridad normal (entre 4-6). Una tabla de los valores potenciales: TaskSettings.Priority propiedad
    • Un valor de 4 tendrá la misma E / S y prioridad de memoria que un proceso interactivo. Los valores de 5 y 6 tendrán menor prioridad de memoria
  6. En el programador de tareas, elimine la tarea que creó inicialmente
  7. En el programador de tareas, en el área de acciones, importe la tarea desde el archivo XML

Desafortunadamente, no hay forma de modificar la prioridad inicial de las tareas programadas desde la GUI.

Jason Mathison
fuente
Gracias por la sugerencia. La prioridad normal del proceso y la prioridad IO son definitivamente parte de ella, y la otra parte es la prioridad de la memoria. Vea la respuesta aceptada para más información.
Charlie
Después de exportar la tarea a un archivo XML, es posible que deba cambiar la codificación de caracteres de Unicode a ANSI. En Windows Server 2008 R2, la exportación es un archivo Unicode y cuando intenta importarlo nuevamente, The format of the task is not valid. The following error was reported: (1,2)::aparece el mensaje de error . Guardar el archivo en ANSI lo resuelve por mí.
Erik Anderson
Muchas gracias, esta es realmente la mejor solución. Como mencionan los documentos, también puede establecer la Prioridad aún más alta (al menos hasta 1), para obtener una mayor prioridad de la CPU.
Runa Aamodt
Para cualquiera que piense que puede modificar esto en el registro, no se moleste, no parece estar allí de una manera agradablemente editable.
Nik
1

Si lo configura para ejecutarse como una tarea programada como Usuario X, y luego inicia sesión como Usuario X antes de que se suponga que se ejecute, debería abrir una ventana en su sesión cuando se ejecute, se ejecutará en su sesión.

Si hace esto, ¿toma el período de tiempo más largo o más corto? No sé qué significará esto, pero puede ser un diferenciador útil. ¿Podría haber algún acceso a la red que tenga la cuenta de usuario cuando inicie sesión, pero no cuando se ejecute como una tarea programada, que necesita tiempo de espera y falla? ¿Es diferente el comportamiento si crea una nueva cuenta de usuario y la ejecuta como una tarea programada en esa cuenta?

Otra idea: al ejecutarlo como una tarea programada, ahora que ha fijado la prioridad en su script, ¿todos los subprocesos se ejecutan como Normal o por debajo de lo normal?

mfinni
fuente
1
Los subprocesos definitivamente se ejecutan como Normal, según lo verificado por procexp / taskman. Creo que lo de la red no lo es, porque no hace ningún acceso sustancial a la red, pero lo comprobaré dos veces. La idea de ejecutar la tarea como interactiva también es interesante, lo intentaré.
Charlie
El proceso en sí no tiene que hacer ningún acceso a la red que conozca para que esto sea un problema. Lea esta publicación de Sysinternals y vea cómo algo aparentemente no relacionado puede causar bloqueos / lentitud. blogs.technet.com/b/markrussinovich/archive/2005/08/28/…
mfinni
1

Tal vez las tareas programadas se ejecutan con una prioridad inferior por defecto.

Úselo priopara forzar una mayor prioridad.

mcandre
fuente
Tienes razón en que corren con menor prioridad, pero como mencioné, ya lo he explicado. A menos que haya otra prioridad que no sea la prioridad del proceso que no conozco.
Charlie
0

al principio: puede usar una prioridad superior a la normal (alta, por ejemplo)

en segundo lugar, debe comprender que la sesión en primer plano requiere algunos recursos, principalmente E / S del disco duro y memoria, por lo que la tarea programada se reduce. para un punto de referencia claro, debe cerrar sesión mientras ejecuta el script de PowerShell

y también puede intentar agregar más memoria / usar ramdrive / trabajo dividido en varios discos duros para acelerar los procesos

evg345
fuente
Gracias por las ideas La máquina tiene mucha memoria y capacidad de E / S, el problema es que las cosas funcionan más lentamente como tareas programadas que interactivamente. Cuando se ejecuta la tarea programada, generalmente no hay una sesión de inicio de sesión interactiva, por lo que creo que ese tampoco es el problema.
Charlie
0

Esta pregunta es de hace un tiempo, y para Windows Server 2008R2. Tenía la misma pregunta, pero para Windows 10. En Windows 10 (verificado en 1703 y 1809), solo establecer la "Prioridad" en 4 mediante xml importado es suficiente para darle la misma Prioridad básica, Prioridad dinámica, Prioridad de E / S y Prioridad de memoria como un proceso iniciado de forma interactiva.

aggieNick02
fuente
0

Aquí hay un fragmento de PowerShell para establecer la prioridad (¡funciona en una sesión remota de PowerShell!):

$taskName = "MyTask" ;`
$currentTask = Get-ScheduledTask -TaskName $taskName ;`
$settings = New-ScheduledTaskSettingsSet ;`
$settings.Priority = 4 ;`
Set-ScheduledTask -TaskName $taskName -Trigger $currentTask.Triggers -Action $currentTask.Actions -Settings $settings -User "NT AUTHORITY\SYSTEM"
Hank Killinger
fuente