2010-03-25 13 views
35

¿Cómo podría generar una carga estable de la CPU en C#, inferior al 100% durante un tiempo determinado? También me gustaría poder cambiar la cantidad de carga después de un cierto período de tiempo. ¿Cómo se recomienda generar picos de uso durante un tiempo muy corto?Simula la carga constante de la CPU y picos

Respuesta

48

En primer lugar, debe comprender que el uso de la CPU siempre es un promedio durante un tiempo determinado. En cualquier momento dado, la CPU está funcionando o no funciona. La CPU nunca está funcionando al 40%.

Sin embargo, podemos simular una carga del 40% en, digamos, un segundo haciendo que la CPU trabaje durante 0,4 segundos y que duerma 0,6 segundos. Eso da una utilización promedio del 40% en ese segundo.

Cortarlo a menos de un segundo, digamos trozos de 100 milisegundos debería dar una utilización aún más estable.

El siguiente método se llevará a un argumento que se desea la utilización y luego utilizar una sola CPU/núcleo a ese grado:

public static void ConsumeCPU(int percentage) 
{ 
    if (percentage < 0 || percentage > 100) 
     throw new ArgumentException("percentage"); 
    Stopwatch watch = new Stopwatch(); 
    watch.Start();    
    while (true) 
    { 
     // Make the loop go on for "percentage" milliseconds then sleep the 
     // remaining percentage milliseconds. So 40% utilization means work 40ms and sleep 60ms 
     if (watch.ElapsedMilliseconds > percentage) 
     { 
      Thread.Sleep(100 - percentage); 
      watch.Reset(); 
      watch.Start(); 
     } 
    } 
} 

estoy usando un stopwatch aquí porque es más preciso que el de la TickCount propiedad, pero también podrías usar eso y usar la resta para verificar si ya has corrido el tiempo suficiente.

Dos cosas a tener en cuenta:

  • en los sistemas de núcleo múltiple, que tendrán que generar un hilo para cada núcleo. De lo contrario, verá que solo se está ejecutando una CPU/núcleo que da aproximadamente el uso de "porcentaje/número de núcleos".
  • Thread.Sleep no es muy preciso. Nunca va a garantizar tiempos exactamente a la milésima de segundo por lo que verá algunas variaciones en los resultados de

Para responder a su segunda pregunta, sobre el cambio de la utilización después de un cierto tiempo, le sugiero que ejecuta este método en uno o más hilos (dependiendo del número de núcleos) y luego cuando desee cambiar la utilización, simplemente detenga esos hilos y genere nuevos con los nuevos valores porcentuales. De esta forma, no tiene que implementar la comunicación de subprocesos para cambiar percentage de un subproceso en ejecución.

13

Sólo en complemento de la respuesta Isak, dejo aquí una implementación simple para múltiples núcleos:

public static void CPUKill(object cpuUsage) 
    { 
     Parallel.For(0, 1, new Action<int>((int i) => 
     { 
      Stopwatch watch = new Stopwatch(); 
      watch.Start(); 
      while (true) 
      { 
       if (watch.ElapsedMilliseconds > (int)cpuUsage) 
       { 
        Thread.Sleep(100 - (int)cpuUsage); 
        watch.Reset(); 
        watch.Start(); 
       } 
      } 
     })); 

    } 

    static void Main(string[] args) 
    { 
     int cpuUsage = 50; 
     int time = 10000; 
     List<Thread> threads = new List<Thread>(); 
     for (int i = 0; i < Environment.ProcessorCount; i++) 
     { 
      Thread t = new Thread(new ParameterizedThreadStart(CPUKill)); 
      t.Start(cpuUsage); 
      threads.Add(t); 
     } 
     Thread.Sleep(time); 
     foreach (var t in threads) 
     { 
      t.Abort(); 
     } 
    } 
+2

i utiliza su función y casi funcionó. 7 de 8 núcleos estaban en el nivel deseado, luego cambié "for (int i = 0; i Joshi

0

Cada vez que se tiene que fijar la variable cpuUsageIncreaseby. por ejemplo:

1- Cpu% de aumento por> cpuUsageIncreaseby% por un minuto. 2- Disminuye a 0% durante 20 segundos. 3- Goto paso 1.

 private void test() 
     { 
      int cpuUsageIncreaseby = 10; 
      while (true) 
      { 
       for (int i = 0; i < 4; i++) 
       { 
        //Console.WriteLine("am running "); 
        //DateTime start = DateTime.Now; 
        int cpuUsage = cpuUsageIncreaseby; 
        int time = 60000; // duration for cpu must increase for process... 
        List<Thread> threads = new List<Thread>(); 
        for (int j = 0; j < Environment.ProcessorCount; j++) 
        { 
         Thread t = new Thread(new ParameterizedThreadStart(CPUKill)); 
         t.Start(cpuUsage); 
         threads.Add(t); 
        } 
        Thread.Sleep(time); 
        foreach (var t in threads) 
        { 
         t.Abort(); 
        } 

        //DateTime end = DateTime.Now; 
        //TimeSpan span = end.Subtract(start); 
        //Console.WriteLine("Time Difference (seconds): " + span.Seconds); 

        //Console.WriteLine("10 sec wait... for another."); 
        cpuUsageIncreaseby = cpuUsageIncreaseby + 10; 
        System.Threading.Thread.Sleep(20000); 
       } 
      } 
     } 
1

Para un uniforme destacando: La respuesta de Isak Savo con una ligera inclinación

int percentage = 80; 
for (int i = 0; i < Environment.ProcessorCount; i++) 
{ 
    (new Thread(() => 
    { 
     Stopwatch watch = new Stopwatch(); 
     watch.Start(); 
     while (true) 
     { 
      // Make the loop go on for "percentage" milliseconds then sleep the 
      // remaining percentage milliseconds. So 40% utilization means work 40ms and sleep 60ms 
      if (watch.ElapsedMilliseconds > percentage) 
      { 
       Thread.Sleep(100 - percentage); 
       watch.Reset(); 
       watch.Start(); 
      } 
     } 
    })).Start(); 
} 
Cuestiones relacionadas