Analyser les performances à l’aide du profilage de l’UC dans le Profileur de performances (C#, Visual Basic, C++, F#)

Une bonne façon de commencer à étudier les problèmes de performance de votre application est de comprendre l’utilisation de l’UC à l’aide d’un profiler d’UC. L'outil de performance Utilisation du processeur de Visual Studio montre le temps de calcul actif du processeur et le pourcentage consacré à l'exécution du code en C++, C#/Visual Basic.

L’outil Utilisation de l’UC peut vous aider à :

  • Diagnostiquer un ralentissement ou un blocage de processus dans le code base de votre équipe. L’outil peut vous aider à diagnostiquer le problème avec le code de production de votre équipe. Il fournit des aperçus automatiques et divers affichages de vos données afin que vous puissiez analyser et diagnostiquer les problèmes de performance.

  • Identifier les problèmes de performance dans les scénarios DevOps. Par exemple, l'outil peut être utile lorsqu'un client signale que certaines requêtes ou commandes ne parviennent pas au site web de vente au détail pendant la haute saison. Souvent, les problèmes sont en production, et il est difficile de déboguer à ce moment-là, mais cet outil peut vous aider à capturer suffisamment d’informations et de preuves concernant le problème. Après la collecte d’un fichier de trace, l’analyse peut rapidement vous aider à comprendre les causes potentielles et donner des suggestions dans le contexte de votre code afin que vous puissiez effectuer les étapes suivantes pour résoudre le problème.

  • Vérifier si le processeur est fortement sollicité Si votre problème de latence n'est pas lié à une requête API, vous pouvez vérifier l'utilisation élevée du processeur et d'autres problèmes connexes à l'aide de l'outil Utilisation du processeur. L’outil Utilisation de l’UC peut vous aider à identifier les goulots d’étranglement afin que vous puissiez affiner l’emplacement à optimiser.

L’outil Utilisation de l’UC est utile à la fois pour les sessions de suivi locales et la production. Vous pouvez lancer l'outil Utilisation du processeur en utilisant le raccourci clavier, Alt+F2, puis en choisissant Utilisation de l’UC, ou en ouvrant une trace déjà collectée à l’aide d’un outil comme dotnet-trace ou dotnet-monitor. (Pour le code de production .NET, il s’agit probablement de la façon dont vous collecteriez les traces.)

Vous pouvez exécuter l'outil Utilisation du processeur sur un projet Visual Studio ouvert, sur une application Microsoft Store installée ou attachée à une application ou un processus en cours d'exécution. Vous pouvez exécuter l’outil Utilisation de l’UC avec ou sans débogage. Pour plus d’informations, consultez Exécution des outils de profilage avec ou sans débogueur.

Les instructions suivantes indiquent comment utiliser l’outil Utilisation de l’UC sans le débogueur, à l’aide du Profileur de performances de Visual Studio. Les exemples utilisent une build Release sur un ordinateur local. Les builds Release fournissent la meilleure vue des performances réelles de l’application. Pour obtenir un didacticiel qui montre comment améliorer les performances à l’aide de l’outil Utilisation de l’UC, consultez le Étude de cas : Guide du débutant pour l'optimisation du code.

En règle générale, c’est l’ordinateur local qui réplique le mieux l’exécution des applications installées. Pour collecter des données à partir d’un appareil distant, exécutez l’application directement sur l’appareil, et non par le biais d’une connexion Bureau à distance.

Collecter les données d’utilisation de l’UC

  1. Dans le projet Visual Studio, définissez la configuration de la solution sur Mise en production et sélectionnez Débogueur Windows local (ou Ordinateur local) comme cible de déploiement.

    Capture d’écran montrant la sélection Mise en production et Ordinateur local.

    Capture d’écran montrant la sélection Mise en production et Ordinateur local.

  2. Sélectionnez Déboguer>Profileur de performances.

  3. Sous Outils disponibles, sélectionnez Utilisation de l’UC, puis Démarrer.

    Capture d’écran montrant Sélectionner l’utilisation du processeur.

    Capture d’écran montrant Sélectionner l’utilisation du processeur.

    Si vous activez l’option Démarrer avec la collecte suspendue avant de démarrer le profileur, les données ne seront collectées que lorsque vous sélectionnez le bouton Enregistrer dans la vue de session de diagnostic.

    Remarque

    Pour plus d’informations sur la manière de rendre l’outil plus efficace, consultez Optimisation des paramètres du Profileur.

  4. Une fois que l’application a démarré, la session de diagnostic commence et affiche les données d’utilisation de l’UC. Quand vous avez terminé la collecte des données, sélectionnez Arrêter la collecte.

    Capture d’écran montrant Arrêter la collecte de données de l’utilisation du processeur.

    Capture d’écran montrant Arrêter la collecte de données de l’utilisation du processeur.

    L'outil Utilisation de l'UC analyse les données et affiche le rapport. 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.

    Capture d’écran montrant le rapport Utilisation du processeur.

    Capture d’écran montrant le rapport Utilisation du processeur.

    Utiliser la liste déroulante Filtre pour sélectionner ou désélectionner des threads à afficher, et utilisez la zone Rechercher pour rechercher un nœud ou un thread spécifique.

Colonnes de données d’utilisation de l’UC

Nom Description
Total UC [unité, %] % total, équation de données

Les millisecondes de temps de calcul du processeur et le pourcentage du processeur utilisé par les appels à la fonction, et les fonctions appelées par la fonction, dans la plage de temps sélectionnée. Cette information est différente du graphe chronologique Utilisation de l’UC, qui compare l’activité totale de l’UC durant une plage de temps à la quantité totale d’UC disponible.
Temps UC exclusif [unité, %] % auto, équation

Les millisecondes de temps de calcul du processeur et le pourcentage du processeur utilisé par les appels à la fonction dans l'intervalle de temps sélectionné, à l'exclusion des fonctions appelées par la fonction.
Module Dans certaines vues, la colonne Module s’affiche et indique le nom du module contenant la fonction.

Analyser les insights sur le processeur

Si un aperçu apparaît dans la section Top Insights, utilisez le lien fourni pour obtenir plus d'informations sur le problème identifié. En outre, si vous utilisez Copilot, le bouton Demander à Copilot ouvrira la fenêtre de discussion de Copilot, et Copilot fournira des suggestions basées sur votre code et les problèmes identifiés.

Pour plus d'informations, voir les aperçus du processeur.

Analyser l’utilisation de l’UC

Pour analyser l’utilisation de l’UC, cliquez sur Ouvrir les détails ou cliquez sur l’une des fonctions principales pour ouvrir la vue Fonctions.

Le rapport fournit différentes vues des données de diagnostic :

  • Appelant/appelé
  • Arborescence des appels
  • Modules
  • Fonctions
  • Graphe de flamme

Pour analyser le rapport, cliquez sur Créer un rapport détaillé.

Le rapport fournit différentes vues des données de diagnostic :

  • Appelant/appelé
  • Arborescence des appels

Dans toutes les vues, à l’exception de Appelant/appelé, le rapport de diagnostic est trié par Total processeur, du plus élevé au plus bas. Changez l’ordre de tri ou la colonne de tri en sélectionnant les en-têtes de colonnes. Vous pouvez double-cliquer sur une fonction qui vous intéresse, et vous verrez la source de la fonction ainsi que l’endroit où le temps est consacré dans cette fonction. Le tableau contient des colonnes avec des données comme le temps passé dans la fonction, y compris les fonctions appelées (Total processeur), et une deuxième colonne qui montre le temps passé dans une fonction, à l’exclusion des fonctions appelées (Temps UC exclusif).

Ces données peuvent vous aider à évaluer si la fonction elle-même est un goulot d’étranglement. Déterminez la quantité de données affichées par la méthode pour voir si du code ou des bibliothèques d’exécution tiers sont la raison pour laquelle vos points de terminaison sont lents ou consomment beaucoup de ressources.

Pour plus d’informations sur l’utilisation du graphe de type flamme, consultez Identifier les chemins chauds avec un graphe de type flamme.

Arbre d'appel de l'utilisation du processeur

Pour afficher l’arborescence des appels, sélectionnez le nœud parent dans le rapport. Par défaut, la page Utilisation de l’UC s’ouvre sur la vue Appelant/appelé. Dans la liste déroulante Affichage actuel, sélectionnez Arborescence des appels.

Vous pouvez cliquer sur les boutons Développer le chemin réactif et Afficher le chemin réactif pour afficher les appels de fonction qui présentent la plus grande consommation du processeur dans l’arborescence des appels.

Structure de l'arborescence des appels

Capture d’écran montrant Structure de l’arborescence des appels.

Capture d’écran montrant Structure de l’arborescence des appels.

Image Description
Étape 1 Le nœud de niveau supérieur de l'arbre d'appel de l'utilisation du processeur, qui représente l'application.
Étape 2 Dans la plupart des applications, quand l’option Afficher le code externe est désactivée, le nœud de second niveau est un nœud [Code externe]. Le nœud contient le code système et framework qui démarre et arrête l’application, dessine l’interface utilisateur, contrôle la planification des threads et fournit d’autres services de bas niveau à l’application.
Étape 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 d'infrastructure de deuxième niveau.
Étape 4 Les nœuds enfants d’une méthode ont 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] .

Code externe

Les fonctions système et framework qui sont exécutées par votre code sont appelées code externe. Les fonctions de code externe 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 ne serez pas intéressé par le code externe ; par conséquent, l’arborescence des appels de l’utilisation de l’UC regroupe les fonctions externes d’une méthode utilisateur en un seul nœud [appel externe] .

Pour afficher les chemins d'appel du code externe, sur la page principale de résumé du rapport (volet de droite), désélectionnez Afficher uniquement mon code dans le menu déroulant Paramètres, puis sélectionnez Appliquer. (La liste déroulante Paramètres est disponible sur la page principale de résumé du rapport, mais pas sur les vues détaillées).

Capture d'écran montrant Paramètres, puis Afficher uniquement mon code.

Les fonctions système et framework qui sont exécutées par votre code sont appelées code externe. Les fonctions de code externe 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 ne serez pas intéressé par le code externe ; par conséquent, l’arborescence des appels de l’utilisation de l’UC regroupe les fonctions externes d’une méthode utilisateur en un seul nœud [Code externe] .

Pour voir les chemins d’appel du code externe, sélectionnez Afficher le code externe dans la liste déroulante Filtrer de la page principale des rapports de diagnostic (volet droit), puis sélectionnez Appliquer. La vue Arborescence des appels de la page Utilisation de l’UC page étend alors les appels de code externe. (La liste déroulante Filtrer est disponible sur la page principale des diagnostics, et non sur les vues détaillées.)

Capture d’écran montrant Afficher le code externe.

Lorsque vous désactivez l'option Afficher uniquement mon code, l'arborescence des appels de la page Utilisation du processeur développe les appels de code externe.

De nombreuses chaînes d’appels de code externe sont profondément imbriquées ; par conséquent, la largeur de la chaîne peut dépasser la largeur d’affichage de la colonne Nom de la fonction. Les noms des fonctions s’affichent ensuite comme indiqué dans l’image suivante.

Capture d’écran montrant le code externe imbriqué dans l’arborescence des appels.

De nombreuses chaînes d’appels de code externe sont profondément imbriquées ; par conséquent, la largeur de la chaîne peut dépasser la largeur d’affichage de la colonne Nom de la fonction. Les noms des fonctions apparaissent alors comme ....

Capture d’écran montrant le code externe imbriqué dans l’arborescence des appels.

Pour rechercher un nom de fonction, utilisez la zone de recherche. Placez le curseur sur la ligne sélectionnée ou utilisez la barre de défilement horizontale pour afficher les données.

Capture d’écran qui montre Rechercher du code externe imbriqué.

Capture d’écran qui montre Rechercher du code externe imbriqué.

Fonctions asynchrones dans l’arborescence des appels de l’utilisation du processeur

Quand le compilateur rencontre une méthode asynchrone, il crée une classe masquée pour contrôler l’exécution de la méthode. Conceptuellement, la classe est une machine à états. Elle a des fonctions générées par le compilateur qui appellent de façon asynchrone les méthodes d’origine ainsi que les rappels, le planificateur et les itérateurs nécessaires pour les exécuter. Quand une méthode parente appelle la méthode d’origine, le compilateur supprime la méthode du contexte d’exécution du parent et exécute les méthodes de la classe masquée dans le contexte du code système et framework qui contrôle l’exécution de l’application. Les méthodes asynchrones sont souvent, mais pas toujours, exécutées sur un ou plusieurs threads différents. Ce code est affiché dans l’arborescence des appels Utilisation de l’UC en tant qu’enfants du nœud [Code externe] situé immédiatement sous le nœud supérieur de l’arborescence.

Dans l’exemple suivant, les deux premiers nœuds sous [Code externe] sont les méthodes générées par le compilateur de la classe de la machine à états. Le troisième nœud est l’appel à la méthode d’origine.

Capture d’écran montrant un nœud asynchrone.

Développez les méthodes générées pour voir ce qui se passe :

Capture d’écran montrant un nœud asynchrone développé.

Capture d’écran montrant un nœud asynchrone développé.

  • MainPage::GetMaxNumberAsyncButton_Click gère simplement la liste des valeurs de la tâche, calcule le nombre maximal de résultats et affiche la sortie.

  • MainPage+<GetMaxNumberAsyncButton_Click>d__3::MoveNext affiche l'activité requise pour planifier et lancer les 48 tâches qui encapsulent l'appel à GetNumberAsync.

  • MainPage::<GetNumberAsync>b__b affiche l’activité des tâches qui appellent GetNumber.

Collecter le nombre d’appels (.NET)

Si vous souhaitez afficher le nombre d’appels dans la vue Fonctions, vous pouvez activer le paramètre avant de démarrer le profileur. Ce paramètre est pris en charge pour des types de projet .NET et nécessite le lancement du processus sous le profileur. Le scénario d’attachement n’est pas pris en charge.

  1. Sélectionnez l’icône Paramètres de l’utilisation du processeur dans le Profileur de performances.

    Capture d’écran montrant l’icône paramètres pour l’utilisation du processeur.

  2. Activez l’option Collecter le nombre d’appels (.NET uniquement).

    Capture d’écran montrant les paramètres pour l’utilisation du processeur.

  3. Collecter les données d'utilisation du processeur.

  4. Ouvrez la vue Fonctions, puis vérifiez que la colonne Nombre d’appels est définie sur visible.

    Si vous ne voyez pas la colonne, cliquez avec le bouton de droite sur un en-tête de colonne pour choisir les colonnes visibles.

    Capture d’écran montrant les données du nombre d’appels.