2010-03-25 11 views
35

Comment générer une charge CPU stable en C#, inférieure à 100% pendant un certain temps? Je voudrais également pouvoir changer la quantité de chargement après une certaine période de temps. Comment recommandez-vous de générer des pics d'utilisation pour très peu de temps?Simulation de la charge du processeur et des pics

Répondre

48

Tout d'abord, vous devez comprendre que l'utilisation du processeur est toujours une moyenne sur une certaine période. À tout moment, le processeur fonctionne ou ne l'est pas. Le processeur ne fonctionne jamais à 40%.

Nous pouvons, cependant, simuler une charge de 40% plus d'une seconde en faisant fonctionner la CPU pendant 0,4 secondes et en dormant 0,6 secondes. Cela donne une utilisation moyenne de 40% sur cette seconde.

Réduire à moins d'une seconde, par exemple 100 morceaux de milliseconde devrait donner une utilisation encore plus stable.

La méthode suivante prendra un argument que l'on souhaite une utilisation et utiliser une seule CPU/core à ce degré:

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

J'utilise un stopwatch ici parce qu'il est plus précis que le l'TickCount propriété, mais vous pouvez également utiliser cela et utiliser la soustraction pour vérifier si vous avez exécuté assez longtemps.

Deux choses à garder à l'esprit:

  • sur les systèmes multi-core, vous devrez frayer un fil pour chaque noyau. Sinon, vous ne verrez qu'un seul processeur/noyau s'exerçant donnant une utilisation approximative du "pourcentage/nombre de cœurs".
  • Thread.Sleep n'est pas très précis. Il ne sera jamais garantir des temps exactement à la milliseconde de sorte que vous verrez quelques variations dans vos résultats

Pour répondre à votre deuxième question, de changer l'utilisation après un certain temps, je vous suggère d'exécuter cette méthode sur un ou plusieurs fils (en fonction du nombre de cœurs) et lorsque vous voulez changer l'utilisation, vous arrêtez simplement ces threads et vous créez de nouveaux threads avec les nouvelles valeurs en pourcentage. De cette façon, vous n'avez pas à implémenter la communication de thread pour modifier percentage d'un thread en cours d'exécution.

13

Juste à ajouter de la réponse Isak, je laisse ici une implémentation simple multi-cœurs:

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 utilisé votre fonction et il a presque fonctionné. 7 sur 8 coeurs étaient au niveau souhaité, puis j'ai changé "pour (int i = 0; i Joshi

0

Chaque fois que vous devez définir la variable cpuUsageIncreaseby. par exemple:

1- Augmentation du pourcentage de cpu par> cpuUsageIncreaseby% pendant une minute. 2- Descendre à 0% pendant 20 secondes. 3- Aller à l'étape 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

Pour un uniforme soulignant: la réponse de Isak Savo avec un léger coup sec

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