2008-08-05 21 views
37

Me preguntaba si existe una manera elegante de establecer la carga máxima de la CPU para un hilo en particular haciendo cálculos intensivos.

En este momento he localizado el ciclo que más tiempo consume en el hilo (solo hace compresión) y uso GetTickCount() y Sleep() con valores codificados. Se asegura de que el ciclo continúe durante un cierto período de tiempo y que duerma durante un tiempo mínimo. Más o menos hace el trabajo, es decir, garantiza que el hilo no usará más del 50% de la CPU.
Sin embargo, el comportamiento depende del número de núcleos de CPU (gran desventaja) y simplemente feo (desventaja más pequeña :)).
¿Alguna idea?Regulación de la CPU en C++

+1

¿Qué comportamiento visible quieres lograr? Es decir, ¿qué quiere este perro guardián de tus hilos? ¿De ninguna manera deberían usar más de, digamos, el 80% de la CPU? ¿Puede la prioridad de la base del proceso de ajuste a Idle posiblemente calmar el WD? – wordmonger

Respuesta

17

No conozco ninguna API que haga que el programador del sistema operativo haga lo que quiera (incluso si su subproceso tiene prioridad de inactividad, si no hay subprocesos de prioridad más alta, se ejecutará el suyo). Sin embargo, creo que puedes improvisar una función de aceleración bastante elegante en función de lo que ya estás haciendo. Esencialmente (no tengo una máquina de desarrollo de Windows a mano):

Elija una cantidad predeterminada de tiempo que el subproceso dormirá en cada iteración. Luego, en cada iteración (o en cada iteración n, tal que la función de regulación por sí mismo no se convierten en una carga significativa de la CPU),

  1. Calcular la cantidad de tiempo de CPU usa el hilo desde la última vez que su función de regulación fue llamado (Llamaré a esto dCPU). Puede usar la API GetThreadTimes() para obtener la cantidad de tiempo que su subproceso se ha estado ejecutando.
  2. Calcule la cantidad de tiempo real transcurrido desde la última vez que se llamó a su función de aceleración (Llamaré a este dClock).
  3. dCPU/dClock es el porcentaje de uso de CPU (de una CPU). Si es más alto de lo que desea, aumente el tiempo de sueño, si es menor, disminuya el tiempo de sueño.
  4. Haga que su hilo duerma durante el tiempo calculado.

Dependiendo de cómo su perro guardián calcule el uso de la CPU, es posible que desee utilizar GetProcessAffinityMask() para averiguar cuántas CPU tiene el sistema. dCPU/(dClock * CPUs) es el porcentaje del tiempo total de CPU disponible.

Aún tendrá que elegir algunos números mágicos para el tiempo de inactividad inicial y la cantidad de incremento/decremento, pero creo que este algoritmo podría ajustarse para mantener un hilo ejecutándose bastante cerca de un determinado porcentaje de CPU.

+0

Si su objetivo es evitar perder tiempo de CPU, una heurística más económica es probablemente una mejor opción. Dependiendo de cuán problemático es que su hilo se muera de hambre bajo una alta carga del sistema, podría * simplemente * verificar el tiempo transcurrido del reloj de pared. En x86, esto es muy barato, porque las funciones de tiempo basadas en 'rdtsc' ni siquiera necesitan ingresar al modo kernel. Realizar múltiples llamadas al sistema incluso iteraciones 'n' es peor que hacer solo una, a menos que le permita aumentar' n' mucho y obtener el comportamiento que desea. –

2

No puedo pensar en ninguna manera multiplataforma de lo que quiere (o cualquier forma garantizada punto) pero como se está utilizando GetTickCount tal vez usted no está interesado en multiplataforma :)

que había utilice las comunicaciones entre procesos y configure los niveles intensivos en niveles agradables para obtener lo que necesita, pero no estoy seguro de que sea apropiado para su situación.

EDIT: Estoy de acuerdo con Bernard por lo que creo que un proceso en lugar de un hilo podría ser más apropiado, pero podría no ser adecuado para sus propósitos.

4

En Linux, puede cambiar la prioridad de programación de un hilo con nice().

+0

Otras plataformas tienen características similares, consulte también: https://stackoverflow.com/questions/18884510/portable-way-of-setting-stdthread-priority-in-c11 Creo que esta puede ser una buena solución al problema, aunque con diferente semántica, es decir, sin una garantía de consumo de CPU del 50% – milianw

2

El problema es que no es normal querer dejar la CPU en reposo mientras tiene trabajo por hacer. Normalmente establece una tarea en segundo plano a la prioridad IDLE, y deja que el SO maneje la programación de todo el tiempo de CPU que las tareas interactivas no utilizan.

Me parece que el problema es el proceso de vigilancia.

Si su tarea en segundo plano está vinculada a la CPU, quiere que ocupe todo el tiempo de CPU no utilizado para su tarea.

Tal vez debería consultar la fijación del programa watchdog?

+1

Es muy razonable querer una CPU inactiva. Tal vez quiera hacer algunos cálculos pero no le importa qué tan rápido se haga, siempre y cuando no active el ventilador de la CPU en su computadora portátil. – Ringding

0

Puede cambiar la prioridad de un hilo, pero cambiar la utilización máxima requeriría polling y hacks para limitar la cantidad de cosas que ocurren, o usar herramientas del sistema operativo que pueden establecer la máxima utilización de un proceso. Sin embargo, no veo ninguna circunstancia en la que desee hacer esto.

Cuestiones relacionadas