Общие шаблоны для неправильно работающих многопоточных приложений

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

Конфликт блокировок и сериализованное выполнение

Результирующий конфликт блокировки в сериализованном выполнении

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

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

Дополнительные сведения см. в публикации "Performance Pattern 1: Identifying Lock Contention" в блоге Хазима Шафи (Hazim Shafi) Parallel Performance Tools For Windows (на английском языке) на веб-сайте блогов MSDN.

Конфликт блокировки

Неравномерное распределение рабочей нагрузки

Неравномерная рабочая нагрузка

При неравномерном распределении рабочей нагрузки между несколькими параллельными потоками в приложении по мере завершения каждого потока образуется своеобразная лестница, как показано на предыдущем рисунке. Обычно время запуска всех параллельных потоков в визуализаторе параллелизма практически совпадает.Однако заканчиваются эти потоки обычно не одновременно, а произвольным образом.Этот шаблон показывает неравномерное распределение работы между группами параллельных потоков, что может ухудшать производительность.Лучший способ решения этой проблемы — переоценка алгоритма, по которому рабочая нагрузка распределяется между параллельными потоками.

Как показано на следующем рисунке, эти признаки могут проявляться в визуализаторе параллелизма в представлении использования ЦП в виде поэтапного снижения уровня использования центрального процессора.

Неравномерная рабочая нагрузка

Превышение лимита подписки

Превышение лимита подписки

В случае превышения лимита подписки число активных потоков процесса превышает число доступных ядер системы.На предыдущем рисунке показаны результаты превышения лимита подписки с явно выраженным наличием приоритетного прерывания во всех активных потоках.Кроме того, на легенде показано, что на приоритетное прерывание затрачена значительная доля времени (84 процентов в данном примере).Это может свидетельствовать о том, что количество параллельных потоков, запрашиваемых процессом в системе, превышает число логических ядер.Однако это может также свидетельствовать о том, что ресурсы, которые предположительно должны были быть доступными для данного процесса, используются в системе другими процессами.

При анализе данной проблемы нужно учитывать следующие особенности.

  • Возможно, превышение лимита подписки является общесистемной проблемой.Следует учитывать, что приоритетное прерывание потоков данного процесса могут также инициировать другие процессы в системе.Если навести указатель на сегмент приоритетного прерывания в представлении потока, отобразится подсказка с указанием потока и процесса, которые инициировали такое прерывание данного потока.Инициировавший прерывание процесс не обязательно выполняется все время, в течение которого данный процесс не выполнялся вследствие приоритетного прерывания, однако эти сведения позволяют определить источник избыточных приоритетных прерываний процесса.

  • Проанализируйте принцип определения процессом надлежащего числа потоков для выполнения на этом этапе работы.Если процесс непосредственно вычисляет число активных параллельных потоков, попытайтесь изменить алгоритм, усовершенствовав подсчет числа доступных в системе логических ядер.Если используется среда выполнения с параллелизмом, библиотека параллельных задач (Task Parallel Library) или PLINQ, эти библиотеки выполняют вычисление количества потоков.

Неэффективный ввод-вывод

Неэффективный ввод-вывод

Избыточное или недостаточное использование ввода-вывода обычно приводит к неэффективности работы приложений.Рассмотрим предыдущий рисунок.В профиле видимой временной шкалы указано, что 42 процента видимого времени выполнения приложений потрачено на ввод-вывод.На временной шкале указано много операций ввода-вывода, что свидетельствует о частом блокировании ввода-вывода в профилируемом приложении.Чтобы просмотреть подробные сведения о характере операций ввода-вывода и блокировании программы, увеличьте проблемные области, проанализируйте профиль видимой временной шкалы, а затем щелкните определенный блок ввода-вывода, чтобы просмотреть текущие стеки вызова.

Колонны блокировок

Колонны блокировок

Колонны блокировок возникают, когда приложение получает блокировки в порядке поступления запросов и когда скорость прибытия на блокировку превышает скорость получения блокировок.При сочетании этих двух условий блокировки начинают резервироваться.Один из способов устранения этой проблемы заключается в использовании "нечестных" блокировок или блокировок, которые предоставляют доступ первому потоку, чтобы он мог перейти в разблокированное состояние.На предыдущем рисунке показано такое построение в колонну.Для решения этой проблемы попытайтесь снизить число конфликтов при синхронизации объектов и прибегнуть к "нечестным" блокировкам.

См. также

Основные понятия

Представление "Потоки" (параллельная производительность)