L'histoire d'un hacker
La date est le 12/02/10. Les jours avant Noël s'égouttent et j'ai quasiment frappé un barrage routier majeur en tant que programmeur Windows. J'utilise AQTime, j'ai essayé somnolent, brillant et très endormi, et au moment où nous parlons, VTune est en train d'installer. J'ai essayé d'utiliser le profileur VS2008, et cela a été positivement punissant et souvent insensible. J'ai utilisé la technique de pause aléatoire. J'ai examiné les arbres d'appels. J'ai déclenché des traces de fonction. Mais le triste fait douloureux de la question est que l'application avec laquelle je travaille compte plus d'un million de lignes de code, avec probablement un autre million de lignes d'applications tierces.
J'ai besoin de meilleurs outils. J'ai lu les autres sujets. J'ai essayé chaque profileur répertorié dans chaque sujet. Il doit simplement y avoir quelque chose de mieux que ces options junky et coûteuses, ou des quantités de travail ridicules pour presque aucun gain. Pour compliquer davantage les choses, notre code est fortement threadé et exécute un certain nombre de boucles Qt Event, dont certaines sont si fragiles qu'elles plantent sous une instrumentation lourde en raison de retards de synchronisation. Ne me demandez pas pourquoi nous exécutons plusieurs boucles d'événements. Personne ne peut me le dire.
Existe-t-il d'autres options du type Valgrind dans un environnement Windows?
Y a-t-il quelque chose de mieux que la longue bande d'outils cassés que j'ai déjà essayés?
Y a-t-il quelque chose conçu pour s'intégrer à Qt, peut-être avec un affichage utile des événements dans la file d'attente?
Une liste complète des outils que j'ai essayés, avec ceux qui étaient vraiment utiles en italique:
- AQTime: Plutôt bien! A quelques problèmes avec la récursivité profonde, mais le graphe d'appel est correct dans ces cas, et peut être utilisé pour dissiper toute confusion que vous pourriez avoir. Ce n'est pas un outil parfait, mais qui vaut la peine d'être essayé. Cela pourrait répondre à vos besoins, et c'était certainement assez bien pour moi la plupart du temps.
- Attaque de pause aléatoire en mode débogage: pas assez d'informations assez souvent.
Un bon outil mais pas une solution complète. - Studios parallèles: l'option nucléaire. Obtrusif, étrange et incroyablement puissant. Je pense que vous devriez passer l'évaluation de 30 jours et déterminer si cela vous convient. C'est vraiment cool aussi.
- AMD Codeanalyst: merveilleux, facile à utiliser, très sujet aux plantages, mais je pense que c'est une question d'environnement. Je recommanderais de l'essayer, car il est gratuit.
- Luke Stackwalker: Fonctionne bien sur les petits projets, c'est un peu essayer de le faire fonctionner sur le nôtre. Quelques bons résultats cependant, et cela remplace définitivement Sleepy pour mes tâches personnelles.
- PurifyPlus: pas de support pour les environnements Win-x64, principalement Windows 7. Sinon excellent. Un certain nombre de mes collègues d'autres ministères ne jurent que par cela.
- VS2008 Profiler: produit une sortie de plus de 100 concerts en mode trace de fonction à la résolution requise. Du côté positif, produit des résultats solides.
- GProf: nécessite que GCC soit même modérément efficace.
- VTune: le support W7 de VTune est à la limite du criminel. Sinon excellent
- PIN: J'aurais besoin de pirater mon propre outil, c'est donc en quelque sorte un dernier recours.
- Sleepy \ VerySleepy: Utile pour les petites applications, mais me manque ici.
- EasyProfiler: Pas mal si cela ne vous dérange pas un peu de code injecté manuellement pour indiquer où instrumenter.
- Valgrind: * nix seulement, mais très bien lorsque vous êtes dans cet environnement.
- OProfile: Linux uniquement.
- Proffy: Ils tirent sur des chevaux sauvages.
Outils suggérés que je n'ai pas essayés:
- XPerf:
- Glowcode:
- Devpartner:
Remarques: environnement Intel pour le moment. VS2008, améliorez les bibliothèques. Qt 4+. Et le misérable de tous: l'intégration Qt / MFC via trolltech.
Maintenant: presque deux semaines plus tard, il semble que mon problème soit résolu. Grâce à une variété d'outils, y compris presque tout sur la liste et quelques astuces personnelles, nous avons trouvé les principaux goulots d'étranglement. Cependant, je vais continuer à tester, explorer et essayer de nouveaux profileurs ainsi que de nouvelles technologies. Pourquoi? Parce que je vous le dois, parce que vous êtes rock. Cela ralentit un peu la chronologie, mais je suis toujours très excité de continuer à essayer de nouveaux outils.
Synopsis
Parmi de nombreux autres problèmes, un certain nombre de composants avaient récemment été basculés vers le modèle de threading incorrect, provoquant de sérieux blocages dus au fait que le code sous nous n'était soudainement plus multithread. Je ne peux pas en dire plus car cela enfreint mon NDA, mais je peux vous dire que cela n'aurait jamais été trouvé par une inspection occasionnelle ou même par un examen normal du code. Sans les profileurs, les callgraphes et les pauses aléatoires en même temps, nous hurlerions toujours notre fureur face au magnifique arc bleu du ciel. Heureusement, je travaille avec certains des meilleurs hackers que j'ai jamais rencontrés, et j'ai accès à un incroyable verset plein d'outils et de gens formidables.
Gentlefolk, j'apprécie énormément cela, et je regrette seulement de ne pas avoir assez de représentants pour récompenser chacun de vous avec une prime. Je pense toujours que c'est une question importante à laquelle obtenir une meilleure réponse que celles que nous avons jusqu'à présent sur les SO.
En conséquence, chaque semaine pendant les trois prochaines semaines, je vais mettre en place la plus grande prime que je puisse me permettre et l'attribuer à la réponse avec le meilleur outil qui, à mon avis, n'est pas de notoriété publique. Après trois semaines, nous espérons avoir accumulé un profil définitif des profileurs, si vous pardonnez mon jeu de mots.
À emporter
Utilisez un profileur. Ils sont assez bons pour Ritchie, Kernighan, Bentley et Knuth. Je me fiche de qui vous pensez être. Utilisez un profileur. Si celui que vous avez ne fonctionne pas, trouvez-en un autre. Si vous n'en trouvez pas, codez-en un. Si vous ne pouvez pas en coder un, ou s'il s'agit d'un petit blocage, ou si vous êtes simplement bloqué, utilisez une pause aléatoire. Si tout le reste échoue, embauchez des étudiants diplômés pour frapper un profileur.
Une vue plus longue
Donc, j'ai pensé que ce serait bien d'écrire un peu de rétrospective. J'ai choisi de travailler de manière intensive avec Parallel Studios, en partie parce qu'il est en fait construit au-dessus de l'outil PIN. Ayant eu des relations universitaires avec certains des chercheurs impliqués, j'ai estimé que c'était probablement une marque d'une certaine qualité. Heureusement, j'avais raison. Bien que l'interface graphique soit un peu affreuse, j'ai trouvé IPS incroyablement utile, même si je ne peux pas le recommander à tout le monde. De manière critique, il n'y a pas de moyen évident d'obtenir le nombre de succès au niveau de la ligne, ce que fournissent AQT et un certain nombre d'autres profileurs, et j'ai trouvé très utile pour examiner le taux de sélection de branche, entre autres. Sur le net, j'ai également aimé utiliser AQTime et j'ai trouvé que leur support était vraiment réactif. Encore une fois, je dois nuancer ma recommandation: Beaucoup de leurs fonctionnalités ne fonctionnent pas très bien, et certaines d'entre elles sont carrément sujettes à des plantages sous Win7x64. XPerf a également fonctionné admirablement, mais est extrêmement lent pour les détails d'échantillonnage nécessaires pour obtenir de bonnes lectures sur certains types d'applications.
À l'heure actuelle, je dois dire que je ne pense pas qu'il existe une option définitive pour profiler le code C ++ dans un environnement W7x64, mais il existe certainement des options qui ne parviennent tout simplement pas à effectuer un service utile.
Réponses:
Première:
Les profileurs d'échantillonnage temporel sont plus robustes que les profileurs d'échantillonnage CPU. Je ne suis pas très familier avec les outils de développement Windows, donc je ne peux pas dire lesquels sont lesquels. La plupart des profileurs utilisent des échantillonnages CPU.
Un profileur d'échantillonnage de processeur récupère une trace de pile toutes les N instructions.
Cette technique révélera des parties de votre code liées au processeur. Ce qui est génial si c'est le goulot de la bouteille dans votre application. Pas si génial si vos threads d'application passent la plupart de leur temps à se battre pour un mutex.
Un profileur d'échantillonnage temporel saisit une trace de pile toutes les N microsecondes.
Cette technique se concentrera sur le code «lent» . Que la cause soit liée au processeur, bloquant les E / S liées, les mutex ou les sections de code de mise en cache. En bref, quel que soit le morceau de code qui ralentit, votre application se démarquera.
Utilisez donc un profileur d'échantillonnage de temps si cela est possible, en particulier lors du profilage de code thread.
Seconde:
Les profileurs d'échantillonnage génèrent des tas de données. Les données sont extrêmement utiles, mais il y en a souvent trop pour être facilement utiles. Un visualiseur de données de profil aide énormément ici. Le meilleur outil que j'ai trouvé pour la visualisation des données de profil est gprof2dot . Ne vous laissez pas tromper par le nom, il gère toutes sortes de sorties de profileur d'échantillonnage (AQtime, Sleepy, XPerf, etc.). Une fois que la visualisation a mis en évidence la ou les fonctions incriminées, revenez aux données de profil brutes pour obtenir de meilleurs indices sur la cause réelle.
L'outil gprof2dot génère une description de graphique à points que vous insérez ensuite dans un outil graphviz . La sortie est essentiellement un callgraph avec des fonctions codées par couleur en fonction de leur impact sur l'application.
Quelques astuces pour que gprof2dot génère une belle sortie.
--skew
de 0,001 sur mes graphiques pour que je puisse facilement voir les chemins de code à chaud. Sinon, leint main()
domine le graphique.--strip
. Cela est particulièrement vrai avec Boost.malloc
est de saccager le tas et de consommer 15%.la source
Que s'est-il passé lorsque vous avez essayé une pause aléatoire? Je l'utilise tout le temps sur une application monstre. Vous avez dit qu'il ne fournissait pas suffisamment d'informations et vous avez suggéré que vous aviez besoin d'une haute résolution. Parfois, les gens ont besoin d'un peu d'aide pour comprendre comment l'utiliser.
Ce que je fais, sous VS, est de configurer l'affichage de la pile pour qu'il ne me montre pas les arguments de la fonction, car cela rend l'affichage de la pile totalement illisible, IMO.
Ensuite, je prends environ 10 échantillons en appuyant sur "pause" pendant le temps que ça me fait attendre . J'utilise ^ A, ^ C et ^ V pour les copier dans le bloc-notes, pour référence. Ensuite, j'étudie chacun d'eux, pour essayer de comprendre ce qu'il était en train d'essayer d'accomplir à ce moment-là.
S'il essayait d'accomplir quelque chose sur 2 échantillons ou plus, et que cette chose n'est pas strictement nécessaire, alors j'ai trouvé un problème en direct et je sais à peu près combien de réparation cela permettra d'économiser.
Il y a des choses que vous n'avez pas vraiment besoin de savoir, comme ne sont pas précises Percents importantes, et ce qui se passe sur le code 3ème partie à l' intérieur est pas important, parce que vous ne pouvez pas faire quoi que ce soit au sujet de ceux . Ce que vous pouvez faire, c'est le riche ensemble de points d'appel dans le code que vous pouvez modifier affiché sur chaque exemple de pile. C'est votre joyeux terrain de chasse.
Exemples du genre de choses que je trouve:
Au démarrage, il peut s'agir d'environ 30 couches de profondeur, en train d'essayer d'extraire des chaînes de caractères internationalisées à partir de ressources DLL. Si les chaînes réelles sont examinées, il peut facilement s'avérer que les chaînes n'ont pas vraiment besoin d'être internationalisées, comme ce sont des chaînes que l'utilisateur ne voit jamais.
Lors d'une utilisation normale, certains codes définissent de manière innocente une propriété Modified dans un objet. Cet objet provient d'une super-classe qui capture le changement et déclenche des notifications qui se répercutent dans toute la structure de données, manipulant l'interface utilisateur, créant et détruisant des obects de manière difficile à prévoir. Cela peut arriver souvent - les conséquences inattendues des notifications.
Remplir une feuille de calcul ligne par ligne, cellule par cellule. Il s'avère que si vous créez la ligne en une seule fois, à partir d'un tableau de valeurs, c'est beaucoup plus rapide.
PS Si vous êtes multi-thread, lorsque vous le mettez en pause, tous les threads s'arrêtent. Jetez un œil à la pile d'appels de chaque thread. Il y a de fortes chances qu'un seul d'entre eux soit le véritable coupable et les autres tournent au ralenti.
la source
J'ai eu du succès avec AMD CodeAnalyst .
la source
Avez-vous une fonction MFC OnIdle? Dans le passé, j'avais une application quasiment en temps réel que je devais réparer qui laissait tomber les paquets série lorsqu'elle était réglée à une vitesse de 19,2K qu'un PentiumD aurait dû être capable de suivre. La fonction OnIdle était ce qui tuait des choses. Je ne sais pas si QT a ce concept, mais je le vérifierais aussi.
la source
Concernant VS Profiler - s'il génère des fichiers aussi volumineux, peut-être que votre intervalle d'échantillonnage est trop fréquent? Essayez de le réduire, car vous avez probablement assez d'échantillons de toute façon.
Et idéalement, assurez-vous de ne pas collecter d'échantillons tant que vous n'avez pas réellement exercé la zone à problème. Commencez donc avec la collection en pause, demandez à votre programme de faire son "activité lente", puis démarrez la collecte. Vous n'avez besoin que de 20 secondes maximum de collecte. Arrêtez la collecte après cela.
Cela devrait vous aider à réduire la taille de vos fichiers d'échantillons et à ne capturer que ce qui est nécessaire pour votre analyse.
la source
J'ai utilisé avec succès PurifyPlus pour Windows. Bien que ce ne soit pas bon marché, IBM propose une version d'essai légèrement paralysée. Tout ce dont vous avez besoin pour le profilage avec quantify sont des fichiers pdb et une liaison avec / FIXED: NO. Seul inconvénient: pas de support pour Win7 / 64.
la source
Easyprofiler - Je ne l'ai pas encore vu mentionné ici, donc je ne sais pas si vous l'avez déjà regardé. Il adopte une approche légèrement différente dans la façon dont il rassemble les données métriques. Un inconvénient de l'utilisation de son approche de profil au moment de la compilation est que vous devez apporter des modifications à la base de code. Ainsi, vous devrez avoir une idée de l'endroit où le ralentissement pourrait être et y insérer du code de profilage.
Si l'on considère vos derniers commentaires, il semble que vous faites au moins des progrès. Peut-être que cet outil pourrait vous fournir des mesures utiles. Si rien d'autre, il a des graphiques et des images vraiment purs: P
la source
Deux autres suggestions d'outils.
Luke Stackwalker a un joli nom (même si cela fait un peu d'efforts à mon goût), cela ne vous coûtera rien et vous obtenez le code source. Il prétend également prendre en charge les programmes multithreads. Cela vaut donc sûrement le détour.
http://lukestackwalker.sourceforge.net/
Aussi Glowcode, que je m'avais indiqué qu'il valait la peine d'utiliser:
http://www.glowcode.com/
Malheureusement, je n'ai pas travaillé sur PC depuis un certain temps, donc je n'ai essayé ni l'un ni l'autre. J'espère que les suggestions sont utiles de toute façon.
la source
Check-out XPerf
Il s'agit d'un profileur gratuit, non invasif et extensible proposé par MS. Il a été développé par Microsoft pour profiler Windows.
la source
Si vous vous méfiez de la boucle d'événements, peut-on remplacer QCoreApplication :: notify () et le profilage manuel de dosome (une ou deux mappages d'expéditeurs / d'événements sur des décomptes / temps)?
Je pense que vous enregistrez d'abord la fréquence des types d'événements, puis examinez ces événements plus attentivement (quel objet l'envoie, que contient-il, etc.). Les signaux entre les threads sont mis en file d'attente implicitement, donc ils se retrouvent dans la boucle d'événements (ainsi que les connexions en file d'attente explicites aussi, évidemment).
Nous l'avons fait pour intercepter et signaler les exceptions dans nos gestionnaires d'événements, donc vraiment, chaque événement passe par là.
Juste une idée.
la source
QObject* object
paramètre. Peut-être que MetaCall est le type pour tous les signaux (semble probable), mais je ne suis pas sûr. Cela va un peu au-delà de mon expérience, mais jeter un coup d'œil dans la source Qt pourrait glaner une certaine vérité. (Ou, posez une question plus pointue sur les appels de signaux en file d'attente ici sur SO .. :)Edit: Je vois maintenant que vous avez mentionné cela dans votre premier message. Bon sang, je n'ai jamais pensé que je serais ce type.
Vous pouvez utiliser Pin pour instrumenter votre code avec une granularité plus fine. Je pense que Pin vous permettrait de créer un outil pour compter le nombre de fois que vous entrez dans une fonction ou le nombre de tours d'horloge que vous y passez, en émulant à peu près quelque chose comme VTune ou CodeAnalyst. Ensuite, vous pouvez dépouiller les fonctions qui sont instrumentées jusqu'à ce que vos problèmes de synchronisation disparaissent.
la source
Je peux vous dire ce que j'utilise tous les jours.
a) Analyste de code AMD
b) VTune.
Il est très bien intégré dans vs2008
une fois que vous connaissez les hotspots, vous devez échantillonner non seulement le temps, mais d'autres choses comme les échecs de cache et l'utilisation de la mémoire. Ceci est très important . Configurez une session d'échantillonnage et modifiez les propriétés. J'échantillonne toujours le temps, la lecture / écriture de la mémoire et les échecs de cache (trois exécutions différentes)
Mais plus que l'outil, vous devez acquérir de l'expérience avec le profilage. Et cela signifie comprendre comment fonctionne le CPU / la mémoire / PCI ... donc, c'est ma 3ème option
c) Tests unitaires
Ceci est très important si vous développez une grosse application qui a besoin d'énormes performances. Si vous ne pouvez pas diviser l'application en plusieurs morceaux, il sera difficile de suivre l'utilisation du processeur. Je ne teste pas tous les cas et toutes les classes, mais j'ai des exécutions codées en dur et des fichiers d'entrée avec des fonctionnalités importantes.
Mon conseil est d'utiliser l'échantillonnage aléatoire dans plusieurs petits tests et d'essayer de standardiser une stratégie de profil.
la source
J'utilise xperf / ETW pour tous mes besoins de profilage. Il a une courbe d'apprentissage abrupte mais est incroyablement puissant. Si vous créez un profil sous Windows, vous devez connaître xperf. J'utilise fréquemment ce profileur pour trouver des problèmes de performances dans mon code et dans le code d'autres personnes.
Dans la configuration que je l'utilise:
C'est beaucoup de données, le tout sur une seule chronologie, pour tous les processus. Aucun autre profileur sous Windows ne peut le faire.
J'ai beaucoup blogué sur la façon d'utiliser xperf / ETW. Ces articles de blog et quelques vidéos de formation de qualité professionnelle peuvent être trouvés ici: http://randomascii.wordpress.com/2014/08/19/etw-training-videos-available-now/
Si vous voulez savoir ce qui pourrait arriver si vous n'utilisez pas xperf, lisez ces articles de blog: http://randomascii.wordpress.com/category/investigative-reporting/ Ce sont des histoires de problèmes de performances que j'ai trouvés dans le code d'autres personnes , qui aurait dû être trouvé par les développeurs. Cela inclut le chargement de mshtml.dll dans le compilateur VC ++, un déni de service dans les fichiers de recherche de VC ++, la limitation thermique dans un nombre surprenant de machines client, la lenteur de la procédure pas à pas dans Visual Studio, une allocation de 4 Go dans un disque dur. pilote de disque, un bogue de performances PowerPoint, etc.
la source
Je viens de terminer la première version utilisable de CxxProf , une bibliothèque de profilage instrumentée manuelle portable pour C ++.
Il remplit les objectifs suivants:
Ces points ont été extraits du wiki du projet , jetez-y un œil pour plus de détails.
Avertissement: Je suis le principal développeur de CxxProf
la source
Juste pour le jeter, même s'il ne s'agit pas d'un profileur à part entière: si tout ce que vous recherchez, ce sont des boucles d'événements qui prennent du temps à traiter un événement, un outil ad-hoc est simple dans Qt. Cette approche pourrait être facilement étendue pour suivre le temps de traitement de chaque événement, quels étaient ces événements, etc. Ce n'est pas un profileur universel, mais un outil centré sur la boucle d'événements.
Dans Qt, tous les appels inter-threads de signal-slot sont délivrés via la boucle d'événements, tout comme les minuteries, les notifications de port réseau et série et toutes les interactions de l'utilisateur. Ainsi, l'observation des boucles d'événements est un grand pas en avant pour comprendre où l'application passe son temps.
la source
DevPartner, initialement développé par NuMega et désormais distribué par MicroFocus, était autrefois la solution de choix pour le profilage et l'analyse de code (fuites de mémoire et de ressources par exemple). Je ne l'ai pas essayé récemment, donc je ne peux pas vous assurer que cela vous aidera; mais j'ai eu une fois d'excellents résultats avec, de sorte que c'est une alternative que je considère de réinstaller dans notre processus de qualité du code (ils fournissent un essai de 14 jours)
la source
bien que votre système d'exploitation soit win7, le programme ne peut pas fonctionner sous xp? que diriez-vous de le profiler sous xp et le résultat devrait être un indice pour win7.
la source
Il y a beaucoup de profileurs listés ici et j'en ai essayé quelques-uns moi-même - mais j'ai fini par écrire le mien basé sur ceci:
http://code.google.com/p/high-performance-cplusplus-profiler/
Cela nécessite bien sûr que vous modifiiez la base de code, mais c'est parfait pour réduire les goulots d'étranglement, devrait fonctionner sur tous les x86 (cela pourrait être un problème avec les boîtiers multi-cœurs, c'est-à-dire qu'il utilise rdtsc, cependant - c'est de toute façon purement indicatif. - donc je trouve que c'est suffisant pour mes besoins ..)
la source
J'utilise Orbit profiler, facile, open source et puissant! https://orbitprofiler.com/
la source