Поделиться через


Упражнение 3. Понимание критического пути и анализа ожидания

Сценарии и действия могут быть неожиданно отложены. Например, открытие вкладки в Microsoft Edge иногда может занять больше времени, чем ожидалось.

Действие определяется как ряд операций, некоторые последовательные и параллельные, которые передаются от события запуска к событию end. Любая пара событий начала и окончания в трассировке может рассматриваться как действие. Самый длинный путь в этой серии операций называется критическим путем. Уменьшение длительности любой операции на критическом пути напрямую сокращает длительность общей активности.

Рекомендуется определить процесс и поток, который завершил действие, и работать в обратном направлении с момента завершения действия. Начните с анализа потока, который завершил действие, чтобы определить, как этот поток провел большую часть своего времени и в каком состоянии: выполняется, готов или ожидает.

Значительное время выполнения указывает на то, что прямое использование ЦП может способствовать длительности критического пути. Время, затраченное в состоянии готовности , указывает на то, что другие потоки влияют на длительность критического пути, препятствуя выполнению потока на критическом пути. Время, затраченное на точки ожидания ввода-вывода, таймеры или другие потоки и процессы на критическом пути, для которого ожидал текущий поток.

Каждый поток, который считывает текущий поток, вероятно, является еще одним звеном в критическом пути и также может быть проанализирован до тех пор, пока не будет учитываться длительность критического пути.

Все необходимые сведения записываются в диаграмму и таблицу загрузка ЦП (точная) в WPA. События использования ЦП, которые регистрируются диспетчером, связаны с коммутаторами контекста. В этой таблице основное внимание уделяется NewThread — потоку, который был переключен, и каждая строка представляет переключатель контекста. Данные собираются для следующей последовательности событий:

Схема, показывающая рабочий процесс сбора данных.

  1. Функция NewThread отключена из-за вызова функции блокировки.

  2. NewThread готов к запуску потоком подготовки.

  3. NewThread включается, тем самым выключая старый поток.

  4. NewThread снова выключается.

Ниже приведены интересные столбцы в таблице Загрузка ЦП (точная).

Столбец Сведения
% загрузки ЦП Загрузка ЦП новым потоком после его переключения. Это значение выражается в процентах от общего времени ЦП за текущий видимый период времени.
Count Число переключений контекста, представленных строкой. Это значение всегда равно 1 для отдельных строк.
Загрузка ЦП (мс) Загрузка ЦП новым потоком после переключения контекста.
NewProcess Процесс нового потока.
NewThreadId Идентификатор нового потока.
NewThreadStack Стек нового потока при его включении. Обычно указывает, что поток был заблокирован или ожидается.
Готовые Время, затраченное потоком в очереди Готово (из-за упреждающего голода или нехватки ЦП).
ReadyingThreadId Идентификатор потока подготовки.
ReadyingProcess Процесс, которому принадлежит поток подготовки.
ReadyThreadStack Стек потока подготовки.
ReadyTime (s) Время подготовки нового потока.
SwitchInTime(s) Время переключения нового потока.
Ожидания (с) Время ожидания потока для логического или физического ресурса. Ожидание заканчивается, когда NewThreadId получает сигнал ReadyingThreadId.

Шаг 1. Запись и открытие трассировки для проблемы с задержкой пользовательского интерфейса

В этом упражнении основное внимание уделяется фиктивному процессу с пользовательским интерфейсом без ответа. Процесс представляет собой простое приложение Windows Forms с кнопкой и текстовым полем. При нажатии кнопки пользовательский интерфейс перестает отвечать на запросы в течение 20 секунд, пока текстовое поле не будет обновлено. Вы проанализируете критический путь этой операции.

Снимок экрана: диалоговое окно

  1. Скачайте UIDelay.exeотсюда.

  2. Запустите UIDelay.exe.

  3. Откройте WPR из меню "Пуск ".

  4. Измените конфигурацию трассировки.

    1. Выберите Первый уровень рассмотрения и загрузка ЦП.

    2. Выберите Общие в качестве сценария производительности.

    3. Выберите Уровень детализации подробно.

      Снимок экрана: диалоговое окно WPR.

  5. Нажмите кнопку Пуск.

  6. В UIDelay.exeнажмите кнопку Щелкните .

    • Дождитесь, пока в текстовом поле не появится сообщение "Готово!"
  7. В WPR сохраните трассировку и откройте ее с помощью WPA.

  8. Откройте меню Трассировка и выберите Настроить путь к символам.

    • Укажите путь к кэшу символов. Дополнительные сведения о символах см. на странице Поддержка символов на сайте MSDN.
  9. Откройте меню Трассировка и выберите Загрузить символы.

Шаг 2. Определение отложенного потока пользовательского интерфейса

Перед выполнением анализа критического пути необходимо сначала определить события запуска и остановки действия.

  1. Найдите граф Задержки пользовательского интерфейса в узле Системное действиеОбозреватель Graph.

    Снимок экрана: пользовательский интерфейс Graph Обозреватель.

  2. Перетащите диаграмму Задержки пользовательского интерфейса на вкладке анализ.

  3. Найдите UIDelay.exe процесс.

    1. Его продолжительность должна составлять около 20 секунд. Это означает, что в потоке пользовательского интерфейсаUIDelay.exeпроизошла задержка в 20 секунд.

    2. Идентификатор потока пользовательского интерфейса отображается в столбце Thread Id (Идентификатор потока ). В этом примере это 24174. Это значение будет отличаться в трассировке, записанной на компьютере. Обязательно запишите идентификатор потока.

      Снимок экрана с примерами данных.

  4. Выберите весь интервал времениUIDelay.exe , щелкните правой кнопкой мыши и увеличьте масштаб.

    Снимок экрана: параметр масштабирования.

Всегда следует увеличивать масштаб регионов, которые вы пытаетесь проанализировать. Это уменьшает количество шума, вызванного несвязанными действиями.

Шаг 3. Анализ критического пути задержки пользовательского интерфейса

Теперь, когда у вас есть отправная точка анализа с идентификатором потока и метками времени, можно начать изучение критического пути действия, чтобы понять последовательность событий, которые приводят к 20-секундной задержке в потоке пользовательского интерфейса.

NewThreadId для этого шага — это поток, определенный на шаге 2 (поток 24174 в UIDelay.exe процессе).

  1. Добавьте диаграмму Загрузка ЦП (точная) на вкладку анализа и примените предустановку "Использование по процессам" потока .

    Снимок экрана: пример данных в WPA с Обозреватель Graph с использованием по процессам, потоку

  2. Щелкните правой кнопкой мыши заголовки столбцов и сделайте столбцы NewThreadStack, ReadyThreadStack и Cpu Usage (ms) видимыми.

  3. Удалите столбцы Ready (us) [Max] и Waits (us) [Max] . Окно просмотра теперь должно выглядеть следующим образом.

    Снимок экрана: пример данных в WPA с увеличенным масштабом с учетом использования ЦП по процессам, потока для ряда с именем UIDelay.exe

  4. Найдите и разверните процессUIDelay.exe в столбце NewProcess и выполните сортировку по waits (us) [Sum] , щелкнув заголовок столбца.

  5. Найдите NewThreadId в процессе UIDelay.exe и проанализируйте его время, затраченное на состояние Выполняется, Готово или Ожидание.

    • В следующем примере можно найти следующее:

      • Поток занимает 10,025 секунды времени ЦП.

      • Поток ожидает 5,159 секунды.

      • Поток находится в состоянии готовности в течение незначительного количества времени (10 мс).

      Снимок экрана: образец данных в WPA с двойной строкой по новому процессу UIDelay.exe масштабированию

    Примечание Вы можете проанализировать 10 секунд активности ЦП с помощью той же методологии, описанной в упражнении 2, шаг 4, используя диаграмму Использование ЦП (выборка) и просмотрев процессUIDelay.exe .

  6. Чтобы узнать, чего ожидал NewThreadId , разверните группу NewThreadId , чтобы отобразить NewThreadStack.

  7. Разверните [Корень] и определите вызовы функции, ведущие к ожиданиям.

    Снимок экрана: пример таблицы в WPA с данными события UIDelay.exe Click

В этом примере UIDelay.exe поток с идентификатором 24174 ожидает вызовов базовой функции блокировки в течение 5,073 секунды при активации функции нажатия кнопки:

  • 5,021 секунды из-за операций под функцией ExecuteWMICall .

  • 35 мс из-за операций под функцией PingServer .

Шаг 3.1. Просмотр пути кода ExecuteWMICall

Если развернуть стек вызовов далее в разделе ExecuteWMICall, вы обнаружите, что поток пользовательского интерфейса фактически находится в спящем режиме в течение 5 секунд, явно вызвав Thread.Sleep.

Снимок экрана: примеры данных в WPA.

Такого поведения следует избегать любой ценой, так как это напрямую влияет на скорость реагирования. Если коду нужно ждать сведений, он должен асинхронно выполнять это в отдельном потоке и использовать метод, управляемый событиями.

Шаг 3.2. Просмотр кода PingServer

Если расширить стек вызовов в разделе PingServer, вы увидите, что поток пользовательского интерфейса имеет зависимости ввода-вывода, так как он отправляет команды Ping по сети.

Снимок экрана: пример таблицы в WPA, на котором показан узел UIDelay.exe, развернутый для System.ni.dll данных

Хотя задержка очень мала (35 мс), ее следует избегать в потоке пользовательского интерфейса. Имейте в виду, что средний пользователь заметит задержку пользовательского интерфейса больше 100 мс. Эта операция может увеличить общее время активности, затраченное более 100 мс, что приводит к тому, что пользователи плохо воспринимают скорость реагирования.

Эти операции должны выполняться асинхронно в отдельном потоке и не блокировать пользовательский интерфейс.