2010-11-08 27 views
6

J'ai une application C# multithread, où la logique de base se trouve dans un gestionnaire d'événements Timer.Elapsed. Le gestionnaire d'événements contient 2 boucles for qui exécute un maximum de n * n = 5 * 5 = 25 times.Application C# - Réduire l'utilisation du processeur

L'application fonctionne bien sur mon PC. J'ai couru VS 2010 Profiler contre l'application et les moyennes d'utilisation du processeur à 20%.

Le testeur de l'entreprise dit que sur son PC, cette dernière saute entre 50% et 100% sur son PC. Cela cause des problèmes de performance pour lui.

  • Y a-t-il quelque chose que je puisse faire pour y remédier?
  • Que signifie vraiment l'utilisation élevée du processeur?
  • Cela pourrait-il avoir un impact sur son PC?
  • Est-il possible de dire à une application d'utiliser seulement X quantité de le CPU?

Toute aide serait appréciée.

+0

Le nombre de fois que la boucle s'exécute signifie quelque chose dans le contexte de ce qu'elle exécute. Si vous exécutez une opération coûteuse 25 fois, cela pourrait être un gros problème. Si vous faites la somme de 25, cela n'aura pas d'importance. – rerun

+0

À quelle fréquence le chronomètre se déclenche-t-il? Et attendez-vous que l'opération se termine avant de recommencer la minuterie, ou continuez-vous à relancer vos boucles, que la précédente soit terminée ou non? –

+0

Le temporisateur s'exécute toutes les secondes. Dans le gestionnaire d'événements timer, j'arrête le timer dans la première ligne de code et le redémarre dans la dernière ligne de code. Effectivement, cela crée juste un délai d'une seconde entre les événements. Le code entre le démarrage et l'arrêt de la minuterie, fait quelques calculs en mémoire sur un ConcurrentDictionary, qui peut croître assez sensiblement. Les calculs sont assez simples mais sont basés sur de grandes quantités de données. Aucune interaction avec l'interface utilisateur ne se produit dans ce gestionnaire d'événements. Par conséquent, je n'utilise pas DispatcherTimer ni BackgroundWorker. Le ConcurrentDictionary est mis à jour par divers événements. – c0D3l0g1c

Répondre

3

vous êtes en demandant et en mode deviner. Oubliez le pourcentage de CPU. Ce que les pros font est de savoir pourquoi le programme passe du temps et si c'est nécessaire.

Ce que vous pouvez faire est d'exécuter simplement ce code à plat dans une longue boucle, et de l'échantillonner. I use this method. Les échantillons de pile atterriront préférentiellement dans les branches lourdes de l'arbre d'appel. Les chances sont que vous pouvez couper certaines de ces branches lourdes et obtenir une belle accélération.

+0

Voir mes commentaires ci-dessus. – c0D3l0g1c

+0

@ c0D3l0g1c: Voici ce qu'il faut savoir sur l'utilisation du processeur. Le processeur est toujours en cours d'exécution. Quand il n'exécute pas de code réel, il exécute le processus inactif. L'utilisation est juste une moyenne mobile à court terme du temps passé en code réel. Pendant que votre processus attend des E/S, il ne s'exécute pas, ce qui se traduit par une utilisation plus faible. Si c'est crissant, c'est plus haut. Cela a peu à voir avec l'efficacité du code. La chose à faire est ce que j'ai dit. Fondamentalement, obtenir l'avance, en trouvant des branches lourdes de l'arbre d'appel que vous pouvez élaguer. –

+0

Merci, c'est logique! Votre article d'un post précédent est utile. – c0D3l0g1c

6
  • exécuter l'événement timer moins fréquemment
  • faire le travail sur un thread de travail (si l'interface utilisateur est au moins réactif)
  • faire moins de travail dans la minuterie (ou le faire plus efficacement)
  • get more CPU

Je suppose que vous voulez vraiment dire la troisième puce, mais nous ne pouvons pas répondre à cette question sans savoir ce que fait le code; mais (suggestions au hasard sans contexte):

  • regarder à tout accès aux collections pour voir s'il y a un endroit pour un dictionnaire, hachage-ensemble, ou similaire
  • vérifier si vous faites de grandes quantités d'IO (en particulier à un DB) qui pourrait être réduite
  • vérifier si vous allez beaucoup de fil commutateurs via Invoke (ou l'équivalent de l'interface utilisateur)
+0

Voir les commentaires ci-dessus. – c0D3l0g1c

1

Ajoutez simplement Thread.Sleep(1); à l'intérieur de votre boucle for. Cela stabilise l'utilisation du processeur et limite l'utilisation du processeur à la vitesse maximale.

0

Peut être votre application exécute plusieurs threads. J'ai le même problème qui exécute plusieurs threads et dans chaque thread il y a une mise à jour continue qui rend l'utilisation de l'application de 50% à 100%. Après avoir étudié le problème, je viens d'introduire le retard en boucle continue du fil (Thread (100)). Cela ramène l'utilisation de l'application à 1% à 3%.