7
votes

Visual Studio C # 2010 Débogu Express fonctionnant plus vite que la libération

J'ai une application Formulaires Windows avec exactement 2 threads. Ces threads ont une interaction nulle avec l'autre, ALA le premier thread fonctionne sans gâcher avec le deuxième fil. Il n'y a pas de synchronisation entre eux, car il n'est pas nécessaire que cela se produise. Le premier thread traite de l'interface utilisateur de l'application, de la modification de couleurs et d'étiquettes et a une minuterie en cours d'exécution pour attraper une partie de l'utilisateur que cette minuterie fente toutes les 200 millisecondes. Le deuxième thread est plus impliqué et traverse constamment son codage jusqu'à l'arrêt de l'utilisateur en sortant de l'application.

Le deuxième fil est d'abord lit de la mémoire et stocke les données dans une liste, utilise ensuite ces données pour effectuer des calculs. J'ai une minuterie de classe de chronomètre pour mesurer le temps nécessaire pour compléter une itération du deuxième fil. Cette minuterie est réinitialisée et démarré au tout début du fil puis arrêté et imprimé à la console une fois que le thread a terminé une itération. C'est là que j'ai reçu mes données de performance. J'ai permis au fil de courir pendant au moins 1000 itérations, puis de faire une moyenne à l'exclusion de la première exécution.

La version de débogage de la construction, c'est la construction qui est exécutée par le Vshost ou lorsque l'on frapperait F5 dans Visual Studio C # 2010 Express. Les horaires moyennes à 0,00035S à 0,35 mS.

Lorsque l'application est exécutée à l'extérieur du Vshost, en frappant CTRL-F5 ou en exécutant l'application à partir de la .EXE qui est produite lors de la construction de la construction. J'ai également utilisé la reconstruction pour tester cela avec un changement absolument zéro. Les horaires moyennes à 0,365 à 365 ms. C'est environ 1000 fois plus lentement avec la version de la libération.

Je suis à une perte complète de ce qui se passe. Que fait le vshost qui permet au programme de fonctionner si rapidement. Je me suis assuré que toute initialisation variable est comptabilisée et correcte. Cela étant dit que je n'ai aucune idée de la raison pour laquelle quelque chose comme ça se produirait. Toute perspicacité de la raison pour laquelle je reçois une telle discothèque?

En tant que note latérale, l'ordinateur que j'utilise est 64 bits a un noyau quad I7 avec un filetage hyper, 16 gigaoctets de RAM et des TWin HD6750. Il ne semble donc pas être un problème d'avoir trop de threads, la seule chose ici qui peut être un problème est le threading hyper.

Un extrait de code sous la forme de ce que fait ma demande. Cependant, il n'est pas possible de donner du code de travail car la lecture de l'adresse de la mémoire est l'endroit où se produit le ralentissement. xxx

}

EDIT :: J'ai essayé la même procédure mais sans utiliser de filetage. J'ai eu la fonction de thread appelée par la minuterie que j'utilisais pour attraper l'entrée de l'utilisateur. Je reçois les mêmes résultats. Cela signifie donc que le filetage ne semble pas être le problème. J'ai également fait le test sur un ordinateur différent et pour une raison quelconque, je ne reçois pas la différence massive. Ce qui me conduit à croire qu'il peut y avoir quelque chose qui ne va pas avec mon ordinateur ou quelque chose traitant de la manière dont mon processeur traite des threads en raison de sa capacité d'hyperfilture. Tout le monde savait si Hyper Whleing provoque des problèmes avec une application multi-threads qui ne l'utilise pas explicitement de l'intérieur du programme. Lequel honnêtement, je n'aurais pas d'indice comment configurer.


12 commentaires

Avez-vous essayé de profiler l'application avec un outil de profilage réel?


+1 pour une question bien étudiée, bien écrite


Difficile d'offrir des conseils sans aucun code à tester.


J'essaie actuellement d'obtenir un extrait de code qui illustrait le problème émettre avec une source dès que possible.


À partir de l'organe de la question, il s'agit d'une question de débogueur ou de débogage attachée, non de débogage vsse (comme états de titre).


Comment lisez-vous les résultats de la chronomètre? - Vous devez avoir des E / S dans Thread2 ou écrire dans une zone lue par Thread1.


À votre premier commentaire, j'étais sous la libération de l'empreinte n'a jamais eu de débogueur attaché, processus hôte ala. Pour effacer les choses, je ne jette que la version de version du fichier créé dans la section de version du dossier BIN. et la version de débogage en frappant F5. Le reste est expliqué. L'extrait ci-dessus est juste une approximation étroite de forme et ce que fait le programme. Je ne trouve pas de meilleure façon de l'illustrer autre que cela sans poster la source entière. Je calcule les résultats de chronomètre dans une fonction non affichée ci-dessus, puis l'avoir sortie sur une fenêtre de la console.


J'ai également suivi des propriétés et supprimai toutes les propriétés de trace et de débogage de la version de la version. J'ai essayé avec et sans optimisation activée. Tous avec les mêmes résultats.


Si je devais deviner, je devinerais que c'est le collectionneur des ordures. En mode de débogage, le collecteur des ordures est beaucoup lazier, de sorte que vous n'avez peut-être pas été collectés, mais réutilisé sur la boucle suivante, où comme en mode de libération, le collecteur des ordures pourrait libérer dès qu'il dépasse de la portée . C'est ma meilleure hypothèse.


Appelez-vous la fonction juste une fois dans le timing? Si la mise en cache ou le compilateur JIT est impliqué, exécutez le chronométrage sur 100 itérations et en gardant le temps le plus rapide contre un appel de synchronisation devrait montrer une différence.


Oui, je fais la moyenne basée sur 1000 itérations. Daren c'est une idée intéressante que je devrai examiner cela.


J'ai un problème connexe. Regardez Stackoverflow.com/Questtions/12295534/...


3 Réponses :


1
votes

Je ne vois rien de là pour dire que vous sélectionnez une version de version. Ceci est une option sur la barre d'outils. Si vous exécutez directement une construction de débogage peut-être qu'il recherche quelque chose qu'il ne trouve pas.

Edit: Sauf le titre que j'ai manqué !!!! : -)


4 commentaires

C'est en fait un point amusant ... et je ne suis pas sûr que si cela aurait nécessairement un impact sur la conclusion du problème, mais comme @Mikekulls suggère, Êtes-vous sûr de l'exécution de la libération et potentiellement optimisées version de l'assemblée?!?


Un autre point: en supposant que ce qui précède n'est pas un problème, votre configuration de débogage et votre configuration de libération ont-elles la même cible de la plate-forme?


Oui, j'ai examiné le fichier .csproj et assuré que, à la fois pour la libération et le débogage, c'est la même plate-forme. Comme pour quelle configuration que j'utilise, je reconstruisant spécifiquement le projet pour chaque exécution et ouvre le débogage configuré, puis la version configurée. J'ai même essayé d'utiliser également la publication. En tant que note latérale, j'ai également exécuté la version de débogage avec le processus hôte, ALA allez à traiter et à décocher l'utilisation du processus hôte de débogage. Avec les mêmes résultats que la version de version. Qui me conduit à croire que cela concerne le processus hôte.


Hahaha, il ne se produit pas de soucis que vous pourriez attraper;)



0
votes

Le problème n'a rien à voir avec l'hyperthreading. Je ne trouve pas le lien, mais il y a une belle description technique de 2004 d'Intel sur la manière dont cela fonctionne (sans battage médiatique marketing). Mais le court est: le noyau 0 est probablement un noyau réel et le noyau 1 est probablement un noyau logique partageant le même matériel que Core 0. Pour notre point de vue (App Devs), les cœurs 0 et 1 sont réels et nous ne le faisons pas Demandez à ce que le noyau 1 est un noyau logique (à l'exception de l'évidence, le noyau logique ne donne qu'albaring 13-30% de performance dans la description technique). Windows fait un très bon travail de planification de threads sur des noyaux réels et logiques. Tout ce que vous avez à faire est de créer deux threads, et Windows s'exécutera chacun sur les noyaux 0 et 1. Vous pouvez désactiver l'hyperthreading dans le BIOS, définir par programme par programme d'affinité de processeur pour vos threads ou définir l'affinité du gestionnaire de tâches, si vous le souhaitez. expérimenter.

Cela étant dit, expérimenter avec hyperthreading ne vous aidera pas à résoudre votre problème. Vous devriez faire comme déjà mentionné et profiler la version de sortie. Cherchez également des erreurs étranges dans le journal des événements. Et exécutez l'explorateur de processus de Sysinternal pour voir si trop de temps est passé dans I / O. Qui sait, peut-être que la version de libération est en quelque sorte déclenchant un comportement bizarre dans un pilote de périphérique sur cette machine.

EDIT: Voil est la description technologique d'Intel (Yay Wikipedia), est en fait à partir de 2002: http://download.intel.com/technology/itj/2002/volume06issue01/vol6iss1_hyper_threading_technology.pdf


0 commentaires

1
votes

Si d'abord, vous devriez faire du profilage de la performance. Utilisez un outil de profilage ou utilisez simplement une minuterie pour imprimer des messages quelque part indiquant combien de temps certaines choses prennent - ceci devrait vous permettre de clouer au moins la ligne de code qui fonctionne lentement même si cela ne vous dit pas pourquoi sa course tellement plus lent sous le débogueur. Sans cette information, tout ce que vous avez, c'est une conjecture.

maintenant, sur la conjecture ...

Je pense que le problème a quelque chose à voir avec l'utilisation de la console, en fonction de ces observations

  • L'écriture sur la fenêtre de la console elle-même est réellement relativement lente - vous pouvez le voir lors de l'exécution d'une application qui écrit beaucoup de choses à la console. Si vous conservez la fenêtre ouverte, il faut une longue période pour exécuter, cependant, si vous minimisez la fenêtre de la console, la même opération peut exécuter un lot plus rapide.
  • Si je comprends bien, vous écrivez 1 message à la console toutes les 0.35ms. C'est un lot de messages.
  • En fonction de la manière dont vous exécutez votre application Visual Studio redirige réellement la sortie de la console à la fenêtre "Sortie" à l'intérieur de Visual Studo lors du débogage.

    Je suppose que la fenêtre de la console dans Visual Studio est beaucoup plus rapide que le mécanisme équivalent utilisé lorsqu'il n'est pas débogué, et que la cause du ralentissement supplémentaire est en réalité votre code de journalisation. Essayez de supprimer votre console à base de journalisation et de vous connecter à un fichier à voir si elle fait une différence, ou même simplement réduire le nombre de fois que vous connectez les messages. E.G. Connectez-vous le temps nécessaire pour compléter 100 itérations - cela réduira l'impact (le cas échéant) que la console a sur votre performance.


0 commentaires