Partager via


Exercice 3 - Comprendre l’analyse du chemin critique et de l’attente

Les scénarios et les activités peuvent être retardés de manière inattendue. Par exemple, l’ouverture d’un onglet dans Microsoft Edge peut parfois prendre plus de temps que prévu.

Une activité est définie comme une série d’opérations, certaines séquentielles et d’autres parallèles, qui passent d’un événement de début à un événement de fin. Toute paire d’événements de début/fin dans une trace peut être vue comme une activité. Le chemin le plus long de cette série d’opérations est appelé chemin critique. La réduction de la durée de toute opération sur le chemin critique réduit directement la durée de l’activité globale.

Il est recommandé d’identifier le processus et le thread qui ont terminé l’activité et de travailler à l’envers à partir du moment où l’activité s’est terminée. Commencez par analyser le thread qui a terminé l’activité pour déterminer comment ce thread a passé la majeure partie de son temps et dans quel état : en cours d’exécution, prêt ou en attente.

Des temps d’exécution significatifs indiquent que l’utilisation directe du processeur peut contribuer à la durée du chemin critique. Le temps passé à l’état prêt indique que d’autres threads contribuent à la durée du chemin critique en empêchant l’exécution d’un thread sur le chemin critique. Le temps passé à attendre pointe vers les E/S, les minuteurs ou d’autres threads et processus sur le chemin critique pour lequel le thread actuel attendait.

Chaque thread qui lit le thread actuel est probablement un autre lien dans le chemin critique et peut également être analysé jusqu’à ce que la durée du chemin critique soit prise en compte.

Toutes les informations requises sont enregistrées dans le graphique et le tableau Utilisation de l’UC (Précis) dans WPA. Les événements d’utilisation du processeur enregistrés par le répartiteur sont associés aux commutateurs de contexte. Ce tableau se concentre sur NewThread , qui est le thread qui a été basculé, et chaque ligne représente un commutateur de contexte. Les données sont collectées pour la séquence d’événements suivante :

Diagramme montrant le flux de travail de collecte de données.

  1. NewThread est éteint en raison d’un appel de fonction bloquant.

  2. NewThread est prêt à s’exécuter par le thread de préparation.

  3. NewThread est basculé, ce qui entraîne le basculement d’un ancien thread.

  4. NewThread est à nouveau éteint.

Voici les colonnes intéressantes de la table Utilisation de l’UC (Précision).

Colonne Détails
% utilisation du processeur Utilisation du processeur du nouveau thread après son basculement. Cette valeur est exprimée en pourcentage du temps processeur total sur la période actuellement visible.
Count Nombre de commutateurs de contexte représentés par la ligne. Il s’agit toujours de 1 pour les lignes individuelles.
Utilisation du processeur (ms) Utilisation du processeur du nouveau thread après le commutateur de contexte.
NewProcess Processus du nouveau thread.
NewThreadId ID de thread du nouveau thread.
NewThreadStack Pile du nouveau thread lorsqu’il est basculé. Indique généralement ce que le thread a été bloqué ou en attente.
Prêt(s) Temps passé par le thread dans la file d’attente Prêt (en raison d’une préemption ou d’une insuffisance de processeur).
ReadyingThreadId ID de thread du thread de préparation.
ReadyingProcess Processus qui possède le thread de préparation.
ReadyThreadStack Pile du thread de préparation.
ReadyTime (s) Heure à laquelle le nouveau thread a été préparé.
SwitchInTime(s) Heure à laquelle le nouveau thread a été activé.
Waits(s) Durée d’attente d’un thread sur une ressource logique ou physique. L’attente se termine lorsque NewThreadId est signalé par ReadyingThreadId.

Étape 1 : Capturer et ouvrir une trace pour un problème de retard de l’interface utilisateur

Cet exercice se concentre sur un processus factice avec une interface utilisateur qui ne répond pas. Le processus est une application Windows Form simple avec un bouton et une zone de texte. Lorsque vous cliquez sur le bouton, l’interface utilisateur ne répond plus pendant 20 secondes jusqu’à ce que la zone de texte soit mise à jour. Vous allez analyser le chemin critique de cette opération.

Capture d’écran de la boîte de dialogue Exemple UIDelage.

  1. Téléchargez UIDelay.exeici.

  2. Lancez UIDelay.exe.

  3. Ouvrez WPR à partir du menu Démarrer .

  4. Modifiez la configuration du suivi.

    1. Sélectionnez Triage de premier niveau et utilisation du processeur.

    2. Sélectionnez Général comme scénario de performances.

    3. Sélectionnez Détaillé comme niveau de détail.

      Capture d’écran de la boîte de dialogue WPR.

  5. Cliquez sur Démarrer.

  6. Dans UIDelay.exe, cliquez sur le bouton Cliquer .

    • Attendez que la zone de texte affiche « Terminé ! ».
  7. Dans WPR, enregistrez la trace et ouvrez-la avec WPA.

  8. Ouvrez le menu Trace et sélectionnez Configurer le chemin des symboles.

    • Spécifiez le chemin du cache de symboles. Pour plus d’informations sur les symboles, consultez la page Prise en charge des symboles sur MSDN.
  9. Ouvrez le menu Trace et sélectionnez Charger des symboles.

Étape 2 : Identifier le thread d’interface utilisateur retardée

Avant d’effectuer une analyse du chemin critique, vous devez d’abord identifier les événements de début et d’arrêt de l’activité.

  1. Recherchez le graphique Retards de l’interface utilisateur dans le nœud Activité système du Explorer Graph.

    Capture d’écran de l’interface utilisateur graph Explorer.

  2. Faites glisser et déposez le graphique Retards de l’interface utilisateur dans l’onglet Analyse.

  3. Recherchez le processus UIDelay.exe .

    1. Sa durée doit être d’environ 20 secondes. Cela indique qu’il y a eu un délai de 20 secondes sur le thread d’interface utilisateur de UIDelay.exe.

    2. L’identificateur de thread d’interface utilisateur s’affiche dans la colonne Id de thread . Dans cet exemple, il s’agit de 24174. Cette valeur sera différente dans la trace que vous avez capturée sur votre ordinateur. Veillez à noter l’ID de thread.

      Capture d’écran des exemples de données.

  4. Sélectionnez l’ensemble de l’intervalle de tempsUIDelay.exe , cliquez avec le bouton droit et zoomez avant.

    Capture d’écran de l’option zoom.

Vous devez toujours effectuer un zoom dans les régions que vous essayez d’analyser. Il réduit la quantité de bruit introduit par des activités non liées.

Étape 3 : Analyser le chemin critique du délai d’interface utilisateur

Maintenant que vous disposez d’un point de départ d’analyse avec l’ID de thread et les horodatages, vous pouvez commencer à explorer le chemin d’accès critique de l’activité pour comprendre la séquence d’événements qui entraînent un retard de 20 secondes sur le thread d’interface utilisateur.

Le NewThreadId de cette étape est le thread que vous avez identifié à l’étape 2 (thread 24174 dans UIDelay.exe processus).

  1. Ajoutez le graphique Utilisation de l’UC (Précise) à l’onglet Analyse et appliquez la présélection Utilisation par processus, Thread .

    Capture d’écran d’exemples de données dans WPA montrant graph Explorer avec utilisation par processus, thread

  2. Cliquez avec le bouton droit sur les en-têtes de colonne et rendez les colonnes NewThreadStack, ReadyThreadStack et Utilisation du processeur (ms) visibles.

  3. Supprimez les colonnes Ready (us) [Max] et Waits (us) [Max]. Votre fenêtre d’affichage doit maintenant ressembler à ceci.

    Capture d’écran d’exemples de données dans WPA montrant un zoom en vue de l’utilisation de l’UC par processus, thread pour la série nommé UIDelay.exe

  4. Recherchez et développez le processus UIDelay.exe dans la colonne NewProcess et triez par Waits (us) [Sum] en cliquant sur l’en-tête de colonne.

  5. Recherchez NewThreadId dans le processus UIDelay.exe et analysez son temps passé dans l’état En cours d’exécution, Prêt ou En attente.

    • Dans l’exemple suivant, vous pouvez trouver les éléments suivants :

      • Le thread consomme 10,025 secondes de temps processeur.

      • Le thread attend 5,159 secondes.

      • Le thread est à l’état prêt pendant une durée négligeable (10 ms).

      Capture d’écran d’exemples de données dans WPA montrant une double ligne à l’échelle du nouveau processus UIDelay.exe

    Note Vous pouvez analyser les 10 secondes d’activité du processeur à l’aide de la même méthodologie décrite dans l’exercice 2, étape 4 à l’aide du graphique Utilisation du processeur (échantillonné) et en examinant le processus UIDelay.exe .

  6. Pour découvrir ce qu’attendait NewThreadId , développez le groupe NewThreadId pour afficher newThreadStack.

  7. Développez [Racine] et identifiez les appels de fonction qui entraînent des attentes.

    Capture d’écran de l’exemple de table dans WPA montrant UIDelay.exe données d’événement Click

Dans cet exemple, UIDelay.exe'ID de thread 24174 attend les appels de fonction bloquants sous-jacents pendant 5,073 secondes lorsque la fonction de clic de bouton est déclenchée :

  • 5,021 secondes sont dues à des opérations sous la fonction ExecuteWMICall .

  • 35 ms sont dues à des opérations sous la fonction PingServer .

Étape 3.1 : Examiner le chemin du code ExecuteWMICall

Si vous développez davantage la pile des appels sous ExecuteWMICall, vous constaterez que le thread d’interface utilisateur est en veille pendant 5 secondes en appelant explicitement Thread.Sleep.

Capture d’écran des exemples de données dans WPA.

Ce type de comportement doit être évité à tout prix, car il a un impact direct sur la réactivité. Si le code doit attendre des informations, il doit le faire de manière asynchrone sur un thread distinct et utiliser une méthode pilotée par les événements.

Étape 3.2 : Examiner le code PingServer

Si vous développez davantage la pile des appels sous PingServer, vous constaterez que le thread d’interface utilisateur a des dépendances d’E/S, car il envoie des commandes Ping sur le réseau.

Capture d’écran de l’exemple de table dans WPA montrant UIDelay.exe nœud développé pour System.ni.dll données

Bien que le délai soit très faible (35 ms), il doit être évité sur un thread d’interface utilisateur. Gardez à l’esprit que la personne moyenne remarquera tout délai d’interface utilisateur supérieur à 100 ms. Cette opération peut augmenter la durée totale d’activité écoulée au-dessus de 100 ms, ce qui entraîne une mauvaise perception de la réactivité des utilisateurs.

Ces opérations doivent se produire de manière asynchrone sur un thread distinct et ne pas bloquer l’interface utilisateur.