Mesurer les performances d’application en analysant l’utilisation du processeur (C#, Visual Basic, C++, F#)

Recherchez les problèmes de performances pendant le débogage avec l’outil de diagnostic Utilisation du processeur intégré au débogueur. Vous pouvez également analyser l’utilisation du processeur sans débogueur attaché ou en ciblant une application en cours d’exécution. Pour plus d’informations, consultez Exécution des outils de profilage avec ou sans débogueur.

Quand le débogueur est en pause, l’outil Utilisation du processeur collecte des informations sur les fonctions qui s’exécutent dans votre application. L’outil répertorie les fonctions qui ont effectué un travail et fournit un graphique chronologique que vous pouvez utiliser pour examiner des segments spécifiques d’une session d’échantillonnage.

Important

Les outils de diagnostic intégrés au débogueur sont pris en charge pour le développement .NET dans Visual Studio (y compris ASP.NET, ASP.NET Core) et pour le développement natif/C++. La charge de travail Visual Studio correspondante est nécessaire. Windows 8 et les versions ultérieures sont nécessaires pour exécuter les Outils de profilage avec le débogueur (fenêtre Outils de diagnostic).

Ce didacticiel présente les procédures suivantes :

  • Collecter les données d'utilisation de l'UC
  • Analyser les données d’utilisation de l’UC

Si Utilisation du processeur ne vous donne pas les données dont vous avez besoin, les autres outils de profilage dans le Profileur de performances fournissent des types d’informations différents qui peuvent vous être utiles. Dans de nombreux cas, le goulot d’étranglement des performances de votre application peut ne pas provenir de votre processeur, mais de la mémoire, de l’interface utilisateur de rendu ou du temps de requête réseau.

Étape 1 : Collecter les données d’utilisation du processeur

  1. Ouvrez le projet que vous voulez déboguer dans Visual Studio, puis définissez un point d’arrêt dans votre application à l’endroit où vous souhaitez examiner l’utilisation du processeur.

  2. Définissez un deuxième point d’arrêt à la fin de la fonction ou de la région de code que vous souhaitez analyser.

    En définissant deux points d’arrêt, vous limitez la collecte de données aux sections de code que vous souhaitez analyser.

  3. La fenêtre Outils de diagnostic apparaît automatiquement, sauf si vous l’avez désactivée. Pour réafficher la fenêtre, cliquez sur Déboguer>Fenêtres>Afficher les outils de diagnostic.

  4. Vous pouvez choisir d’afficher Utilisation de la mémoire, Utilisation de l’UC ou les deux, avec le paramètre Sélectionner les outils de la barre d’outils. Si vous exécutez Visual Studio Enterprise, vous pouvez également activer ou désactiver IntelliTrace dans Outils>Options>IntelliTrace.

    Screenshot that shows Diagnostics Tools.

    Screenshot that shows Diagnostics Tools.

    Nous allons nous intéresser principalement à l’utilisation du processeur. Vérifiez donc que l’outil Utilisation de l’UC est activé (il est activé par défaut).

  5. Cliquez sur Déboguer>Démarrer le débogage (ou bien sur Démarrer dans la barre d’outils, ou sur F5).

    Lorsque l’application est chargée, la vue Résumé des outils de diagnostics s’affiche. Pour ouvrir la fenêtre, cliquez sur Déboguer>Fenêtres>Afficher les Outils de diagnostic.

    Screenshot that shows Diagnostics Tools Summary Tab.

    Screenshot that shows Diagnostics Tools Summary Tab.

    Pour plus d’informations sur les événements, consultez Searching and filtering the Events tab of the Diagnostic Tools window.

  6. Exécutez le scénario qui doit provoquer le premier point d’arrêt.

  7. Pendant que le débogueur est suspendu, activez la collecte des données d’utilisation du processeur, puis ouvrez l’onglet Utilisation de l’UC.

    Screenshot that shows Diagnostics Tools enable CPU profiling.

    Screenshot that shows Diagnostics Tools enable CPU profiling.

    Quand vous choisissez Enregistrer le profil du processeur, Visual Studio commence à enregistrer vos fonctions, ainsi que la durée de leur exécution. Vous pouvez uniquement afficher les données collectées lorsque votre application s’interrompt à un point d’arrêt.

  8. Appuyez sur F5 pour exécuter l’application jusqu’au deuxième point d’arrêt.

    Vous disposez maintenant de données de performances pour votre application, et plus spécifiquement pour la région de code qui s’exécute entre les deux points d’arrêt.

    Le profileur commence la préparation des données de thread. Attendez qu’elle se termine.

    Screenshot that shows Diagnostics Tools preparing threads.

    Screenshot that shows Diagnostics Tools preparing threads.

    L’outil Utilisation de l’UC affiche le rapport sous l’onglet Utilisation de l’UC.

    Screenshot that shows Diagnostics Tools CPU Usage Tab.

    Screenshot that shows Diagnostics Tools CPU Usage Tab.

  9. Si vous souhaitez analyser une région de code plus spécifique, sélectionnez une région (qui affiche les données de profilage) dans la chronologie du processeur.

    Screenshot that shows Diagnostics Tools selecting a time segment.

    Screenshot that shows Diagnostics Tools selecting a time segment.

    À ce stade, vous pouvez commencer à analyser les données. Si vous rencontrez des problèmes lors de la collecte ou de l’affichage des données, consultez Résoudre les erreurs de profilage et corriger les problèmes.

    Conseil

    Quand vous essayez d’identifier les problèmes de performances, prenez plusieurs mesures. Les performances varient naturellement d’une exécution à l’autre, et les chemins de code s’exécutent généralement plus lentement la première fois en raison d’un travail d’initialisation ponctuel, comme le chargement des DLL, les méthodes de compilation JIT et l’initialisation des caches. En prenant plusieurs mesures, vous obtenez une meilleure idée de la plage et de la médiane de la métrique affichée, ce qui vous permet de comparer les performances d’état stable d’une zone de code par rapport à la première fois.

Étape 2 : Analyser les données d’utilisation de l’UC

Nous vous recommandons de commencer à analyser vos données en examinant la liste des fonctions située sous l’onglet Utilisation de l’UC, en identifiant les fonctions qui effectuent la plus grande partie du travail, puis en analysant ces fonctions les unes après les autres.

  1. Dans la liste des fonctions, examinez celles qui effectuent le plus de travail.

    Screenshot that shows Diagnostics Tools CPU Usage Function List.

    Screenshot that shows Diagnostics Tools CPU Usage Function List.

    Astuce

    Les fonctions sont classées par ordre et ce sont celles qui effectuent le plus de travail qui figurent en haut de la liste (elles ne sont pas classées selon leur ordre d’appel). Ainsi, vous pouvez identifier rapidement les fonctions avec les temps d’exécution les plus longs.

  2. Dans la liste, double-cliquez sur l’une des fonctions d’application qui effectuent le plus de travail.

    Quand vous double-cliquez sur une fonction, la vue Fonctions s’ouvre dans le volet gauche. Sélectionnez la vue Appelant/appelé dans le menu déroulant.

    Screenshot that shows Diagnostics Tools Caller Callee View.

    Dans cette vue, la fonction sélectionnée s’affiche dans le titre et dans la zone Fonction actuelle (DoWork, dans cet exemple). La fonction qui a appelé la fonction active s’affiche sur la gauche sous Fonctions appelantes, et toutes les fonctions appelées par la fonction active s’affichent dans la zone Fonctions appelées sur la droite. Vous pouvez sélectionner l’une ou l’autre de ces zones pour modifier la fonction active.

    Cette vue montre la durée totale (en ms), ainsi que le pourcentage du temps global d’exécution de l’application, nécessaires à l’exécution de la fonction. La section Corps de la fonction montre également la durée totale (et le pourcentage correspondant) passée dans le corps de la fonction, à l’exclusion du temps passé dans les fonctions appelantes et appelées.

    Lorsque vous double-cliquez sur une fonction, la vue Appelant/appelé s’ouvre dans le volet gauche.

    Screenshot that shows Diagnostics Tools Caller Callee View.

    Dans cette vue, la fonction sélectionnée apparaît dans le titre et dans la zone Fonction active (ici, GetNumber). La fonction qui a appelé la fonction active s’affiche sur la gauche sous Fonctions appelantes, et toutes les fonctions appelées par la fonction active s’affichent dans la zone Fonctions appelées sur la droite. Vous pouvez sélectionner l’une ou l’autre de ces zones pour modifier la fonction active.

    Cette vue montre la durée totale (en ms), ainsi que le pourcentage du temps global d’exécution de l’application, nécessaires à l’exécution de la fonction. La section Corps de la fonction montre également la durée totale (et le pourcentage correspondant) passée dans le corps de la fonction, à l’exclusion du temps passé dans les fonctions appelantes et appelées. (Dans cet exemple, 2367 ms sur 2389 ont été passées dans le corps de la fonction. Les 22 ms restantes ont été passées dans le code externe appelé par cette fonction.)

    Conseil

    Des valeurs élevées dans le corps de la fonction peuvent indiquer un goulot d’étranglement de performances au sein de la fonction.

  3. Pour voir l’ordre d’appel des fonctions, sélectionnez Arborescence des appels dans la liste déroulante située en haut du volet.

    Chaque zone numérotée dans l'illustration est en rapport avec une étape de la procédure.

    Diagnostics Tools Call Tree

    Image Description
    Step 1 Le nœud de premier niveau des arborescences d'appels de l'outil Utilisation de l'UC est un pseudo-nœud
    Step 2 Dans la plupart des applications, quand l'option Afficher le code externe est désactivée, le nœud de deuxième niveau est un nœud [Code externe] contenant le code système et de l'infrastructure qui démarre et arrête l'application, dessine l'interface utilisateur, contrôle la planification des threads et fournit d'autres services de niveau inférieur à l'application.
    Step 3 Les enfants du nœud de deuxième niveau sont les méthodes en code utilisateur et des routines asynchrones appelées ou créées par le code système et framework de deuxième niveau.
    Step 4 Les nœuds enfants d'une méthode contiennent des données seulement pour les appels de la méthode parente. Lorsque l'option Afficher le Code externe est désactivée, les méthodes d'application peuvent également contenir un nœud [Code externe] .

    Voici davantage d’informations sur les valeurs de colonne :

    • La section Total UC (ms) montre la quantité de travail effectué par la fonction et toute autre fonction qu’elle a appelée. Les valeurs d’UC total élevées indiquent les fonctions les plus coûteuses.

    • La colonne Processeur auto (ms) indique la quantité de travail effectué par le code dans le corps de la fonction, à l’exception du travail effectué par les fonctions qu’elle a appelées. Des valeurs élevées dans la colonne Processeur auto (ms) peuvent indiquer un goulot d’étranglement des performances au sein de la fonction.

    • Modules Nom du module contenant la fonction, ou nombre de modules contenant les fonctions dans un nœud [Code externe].

    Pour afficher les appels de fonction qui présentent la plus grande consommation du processeur dans l’arborescence des appels, cliquez sur Développer le chemin réactif.

    Screenshot that shows Diagnostics Tools Hot Path.

    Note

    Si vous voyez du code dans l’arborescence des appels marqués comme du code « interrompu » ou « pile intraitable », cela signifie que les événements de suivi d’événements pour Windows (ETW) ont probablement été supprimés. Essayez de collecter la même trace une deuxième fois pour résoudre le problème.

Afficher le code externe

Le code externe correspond aux fonctions des composants système et de framework exécutés par le code que vous écrivez. Le code externe inclut les fonctions qui démarrent et arrêtent l'application, dessinent l'interface utilisateur, contrôlent les threads et fournissent d'autres services de bas niveau à l'application. Dans la plupart des cas, vous n’êtes pas intéressé par le code externe. L’outil Utilisation de l’UC regroupe donc les fonctions externes d’une méthode utilisateur au sein d’un même nœud [Code externe].

Si vous voulez afficher les chemins d’appel du code externe, choisissez Afficher le code externe dans la liste Filtrer la vue, puis Appliquer.

Screenshot that shows Choose Filter View, then Show External Code.

N'oubliez pas que de nombreuses chaînes d'appel en code externe sont profondément imbriquées, la largeur de la colonne Nom de fonction ne peut pas dépasser la largeur d'affichage de presque tous les moniteurs d'ordinateur, sauf les plus larges. Si tel est le cas, les noms de fonction sont affichés sous forme de […].

Utilisez la zone de recherche pour trouver le nœud que vous cherchez, puis utilisez la barre de défilement horizontal pour afficher les données dans la vue.

Conseil

Si vous profilez du code externe qui appelle des fonctions Windows, vous devez vérifier que vous disposez des fichiers .pdb les plus récents. Sans ces fichiers, vos vues de rapports répertorient des noms de fonctions Windows cryptés et difficiles à comprendre. Pour vérifier si vous disposez des fichiers nécessaires, consultez Spécifier des fichiers de symboles (.pdb) et des fichiers sources dans le débogueur.

Étapes suivantes

Dans ce didacticiel, vous avez appris comment collecter et analyser les données d’utilisation de l’UC. Si vous avez déjà terminé la visite guidée du profileur, vous pouvez consulter une approche générale de l’optimisation du code à l’aide des outils de profilage.

Dans ce tutoriel, vous avez appris à collecter et analyser les données d’utilisation du processeur pendant le débogage. Vous pouvez en savoir plus sur le profilage des builds Release avec le Profileur de performances.