2017-09-22 12 views
0

Je suis relativement nouveau pour les algorithmes et les bancs de performance, mais j'ai quelques questions.C# fluctuation de performance dans l'algorithme

J'ai écrit un algorithme que je voulais être capable de traiter en petites itérations à la fois pour limiter la perturbation sur une boucle de processus déjà exigeante. Mon objectif était de traiter moins de 1ms à chaque itération donc avoir une performance assez constante semble assez important. Malheureusement, après avoir appliqué un poids de processus pour faire la moyenne de l'algorithme à 0,5 ms, j'ai parfois atteint des temps de plus de 20 ms. J'ai remarqué que la collecte de données causerait quelques problèmes (je suppose que ça bouge en mémoire?) Que j'ai résolus depuis mais qui ont quand même des fluctuations de performance.

J'ai donc créé une méthode vide ici. Même ici, je reçois ces hauts moments occasionnels.

public void DoTask() 
    { 
     for (int i = 0; i < 100000; i++) 
     { 
      //do nothing 
     } 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     DoTask(); //burn 

     var watch = new Stopwatch(); 
     watch.Start(); 

     double time; 
     for (int j = 0; j < 20; j++) 
     { 
      for (int i = 0; i < 1000; i++) 
      {     
       time = watch.ElapsedTicks; 

       DoTask(); 

       time = watch.ElapsedTicks - time; 

       LongestTime = Math.Max(LongestTime, time); 

       TotalTime += time; 

       Count++; 
      } 
      double avgTime = TotalTime/Count; 

      MessageBox.Show($"Longest time: {ToMs(LongestTime).ToString("#.##")} Avg time: {ToMs(avgTime).ToString("#.##")}"); 
      TotalTime = 0; 
      Count = 0; 
      LongestTime = 0; 
     } 
    } 

le plus long temps: 13,04 Moy temps: .01

Ce qui est à l'origine que cela se produise? Est-ce quelque chose qui est hors de mon contrôle?

Merci.

+0

Vous ne pouvez pas garantir un temps d'exécution déterministe dans une application .NET. Il y a un garbage collector sur lequel vous n'avez aucun contrôle. .NET n'est pas adapté aux applications "en temps réel". – dymanoid

+0

DoTask() est dans le post - Il ne fait rien. –

+0

N'oubliez pas non plus que vous travaillez sur un système d'exploitation multitâche, il est donc probable que certains de vos calculs seront mis en attente alors que d'autres programmes auront un peu de temps CPU. – fvu

Répondre

1

Il s'agit en fait davantage d'un problème Windows (ou de tout système d'exploitation qui prend en charge le multitâche mais n'est pas un système d'exploitation en temps réel, qui couvre tous les systèmes d'exploitation client). Tous les systèmes d'exploitation multitâche standard donnent à chaque thread une période de temps pendant laquelle le thread donné fonctionnera sans interruptions et passera potentiellement à un autre thread. Si l'exécution de votre étape est suspendue au milieu en faveur d'un autre temps de thread mesuré par Stopwatch sera essentiellement durée de thread attendait de continuer l'exécution (qui dans Windows dans ~ 15ms par défaut).

Il est difficile de mesurer le temps correctement et il vaut mieux le laisser aux spécialistes - profileurs.

Si vous voulez obtenir légèrement des mesures plus cohérentes avec juste des minuteries en cours - augmenter la priorité du thread qui exécute votre code. De cette façon, le thread aura moins de chance d'être suspendu au profit d'autres threads.

Notes:

  • systèmes d'exploitation en temps réel nécessitent généralement une certaine coopération de l'exécution du code pour garantir le temps d'exécution non interrompue. Aussi, je ne crois pas qu'il existe un tel système d'exploitation qui supporte C#.
  • même dans un système d'exploitation non multitâche comme MS DOS, vous pouvez voir des fluctuations aléatoires du temps mesurées de la même manière que les OS doivent gérer les interruptions des périphériques (disque, clavier, minuterie) pour la durée du code de gestion des interruptions (généralement de petite durée, mais le problème est toujours présent).
  • Le code .Net ajoute des préoccupations supplémentaires car il doit effectuer une récupération de place qui peut avoir lieu à tout moment (c'est-à-dire en raison d'une allocation sur un autre thread). Plus d'infos Fundamentals of Garbage Collection.
+0

Vraiment instructif. Merci. –