Simular carga y picos de CPU constantes

¿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?

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% sobre, 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.

Reducirlo 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 tomará un argumento que es la utilización deseada y luego utilizará una sola CPU / núcleo en 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 cronómetro porque es más preciso que la propiedad TickCount , pero también puedes usarlo y usar la resta para verificar si ya has corrido el tiempo suficiente.

Dos cosas para tener en cuenta:

  • en sistemas multi core, tendrás 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 garantizará los tiempos exactamente al milisegundo, por lo que verá algunas variaciones en sus resultados

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

Solo agrego la respuesta de Isak, dejo aquí una implementación simple para multinúcleo:

  public static void CPUKill(object cpuUsage) { Parallel.For(0, 1, new Action((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 threads = new List(); 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(); } } 

Para un estrés uniforme: la respuesta de Isak Savo con un ligero ajuste

 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(); } 

Cada vez que tenga que establecer la variable cpuUsageIncreaseby. por ejemplo:

1- Cpu% de aumento por> cpuUsageIncreaseby% por un minuto. 2- Baje al 0% por 20 segundos. 3- Ir al 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 threads = new List(); 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); } } }