Beyond Stack Sampling: С++ Profilers

Хакерская сказка

Дата 12/02/10. За несколько дней до Рождества капают, и я довольно сильно ударил по главному дорожному блоку в качестве программиста окон. Я использую AQTime, я пробовал сонный, блестящий и очень сонный, и, как мы говорим, VTune устанавливает. Я попытался использовать профилировщик VS2008, и он был позитивно наказан, а также часто бесчувственным. Я использовал случайную паузу. Я исследовал колл-деревья. Я уволил функции следов. Но печальный болезненный факт заключается в том, что приложение, с которым я работаю, содержит более миллиона строк кода, и, возможно, более миллиона ссылок на сторонние приложения.

Мне нужны лучшие инструменты. Я прочитал другие темы. Я опробовал каждый профилировщик, указанный в каждой теме. Там просто должно быть что-то лучше, чем эти сумасшедшие и дорогие варианты, или смехотворное количество работы почти без выгоды. Чтобы еще больше усложнить ситуацию, наш код сильно пронизан резьбой и запускает ряд циклов событий Qt, некоторые из которых настолько хрупки, что они вылетают из-под сильного инструментария из-за задержки времени. Не спрашивайте меня, почему мы запускаем несколько циклов событий. Никто не может мне сказать.

Есть ли еще какие-либо опции по линиям Valgrind в среде Windows?
Есть ли что-то лучше, чем длинный валок сломанных инструментов, который я уже пробовал?
Есть ли что-либо, предназначенное для интеграции с Qt, возможно, с полезным отображением событий в очереди?

Полный список инструментов, которые я пробовал, с теми, которые были действительно полезны курсивом:

  • AQTime: Очень хорошо! Имеет некоторые проблемы с глубокой рекурсией, но граф вызовов корректен в этих случаях и может использоваться для устранения любой путаницы, которую вы могли бы иметь. Не идеальный инструмент, но стоит попробовать. Это может удовлетворить ваши потребности, и это, безусловно, было достаточно для меня большую часть времени.
  • Случайная приостановка атаки в режиме отладки: недостаточно информации о времени.
    Хороший инструмент, но не полное решение.
  • Параллельные студии: ядерный вариант. Навязчивый, странный и безумно мощный. Я думаю, вы должны поразить 30-дневную оценку и выяснить, хорошо ли она подходит. Это просто чертовски круто, тоже.
  • AMD Codeanalyst: Замечательный, простой в использовании, очень подверженный сбою, но я думаю, что это вещь для окружающей среды. Я бы рекомендовал попробовать, так как это бесплатно.
  • Luke Stackwalker: отлично работает на небольших проектах, он немного пытается заставить его работать над нашим. Однако некоторые хорошие результаты, и это определенно заменяет Sleepy для моих личных задач.
  • PurifyPlus: нет поддержки для сред Win-x64, в первую очередь Windows 7. В противном случае отлично. Ряд моих коллег из других отделов клянутся им.
  • VS2008 Profiler: Производит вывод в диапазоне 100 + концертов в режиме трассировки функции с требуемым разрешением. С положительной стороны получаются солидные результаты.
  • GProf: требуется, чтобы GCC был даже умеренно эффективным.
  • VTune: VTune W7 поддерживает границы на криминальном уровне. В противном случае отлично
  • ПИН: мне нужно взломать собственный инструмент, так что это последнее средство.
  • Sleepy\VerySleepy: полезен для небольших приложений, но не позволяет мне здесь.
  • EasyProfiler: неплохо, если вы не против немного введенного вручную кода, чтобы указать, где инструмент.
  • Valgrind: * nix только, но очень хорошо, когда вы находитесь в этой среде.
  • OProfile: только Linux.
  • Proffy: Они стреляют в диких лошадей.

Рекомендуемые инструменты, которые я не пробовал:

  • XPerf:
  • Glowcode:
  • Devpartner:

Примечания: Intel на данный момент. VS2008, повысить библиотеки. Qt 4+. И жалкий жужжащий из всех: интеграция Qt/MFC через trolltech.


Теперь: Почти две недели спустя, похоже, моя проблема решена. Благодаря множеству инструментов, включая почти все в списке и пару моих личных трюков, мы обнаружили основные узкие места. Тем не менее, я собираюсь продолжать тестирование, изучение и тестирование новых профилировщиков, а также новых технологий. Зачем? Потому что я обязан вам, ребята, потому что вы, ребята, рок. Это немного замедляет временную шкалу, но я все еще очень рад продолжить поиск новых инструментов.

Сводка
Среди многих других проблем недавно был переключен ряд компонентов на неправильную модель потоковой передачи, что вызвало серьезные зависания из-за того, что код под нами внезапно переставал многопоточно. Я не могу сказать больше, потому что это нарушает мою NDA, но я могу сказать вам, что это никогда не было бы обнаружено в результате случайной проверки или даже при обычном просмотре кода. Без профилировщиков, колл-графов и случайных пауз в соединении мы все равно будем кричать о нашей ярости на красивой голубой дуге неба. К счастью, я работаю с лучшими хакерами, которых я когда-либо встречал, и у меня есть доступ к удивительному "стиху, полному отличных инструментов и отличных людей".

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

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

Вынос
Используйте профилировщик. Они достаточно хороши для Ритчи, Кернигана, Бентли и Кнута. Мне все равно, кто ты такой. Используйте профилировщик. Если тот, который у вас есть, не работает, найдите другого. Если вы не можете найти его, введите код. Если вы не можете закодировать один или небольшую зависать, или вы просто застряли, используйте случайную паузу. Если все остальное не удастся, нанять некоторых студентов-градиентов, чтобы избить профайлера.

<ч/" > Более длинный просмотр
Итак, я подумал, что было бы неплохо написать ретроспективу. Я решил активно работать с Parallel Studios, отчасти потому, что он фактически построен поверх инструмента PIN. Имея академические отношения с некоторыми из вовлеченных исследователей, я чувствовал, что это, вероятно, является признаком некоторого качества. К счастью, я был прав. Хотя GUI немного ужасен, я нашел IPS невероятно полезным, хотя я не могу с комфортом рекомендовать его всем. Критически, нет очевидного способа получить число попаданий на уровне строк, что-то, что AQT и ряд других профилировщиков обеспечивают, и я нашел очень полезным для изучения скорости выбора ветки, среди прочего. В сети я тоже наслаждался AQTime, и я нашел, что их поддержка очень отзывчива. Опять же, я должен квалифицировать свою рекомендацию: многие из их функций не работают так хорошо, и некоторые из них прямо подвержены сбоям на Win7x64. XPerf также отлично работает, но он мучительно медленный для деталей выборки, необходимых для хорошего чтения в некоторых видах приложений.

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

Ответ 1

Во-первых:

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

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

Профайлер временной выборки захватывает трассировку стека каждые N микросекунд.
Этот метод будет нулевым в "медленном" коде. Независимо от того, связана ли причина с ЦП, блокировка привязки IO, привязка к mutex или фрагменты кода для кэширования. Короче говоря, когда-либо часть кода замедляется, ваше приложение будет выдающимся.

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

Второе:

Пробоотборники сэмплирования генерируют данные. Данные чрезвычайно полезны, но часто бывает слишком много, чтобы их было легко использовать. Визуализатор профильных данных здесь чрезвычайно помогает. Лучший инструмент, который я нашел для визуализации данных профиля, - gprof2dot. Не позволяйте имени обмануть вас, он обрабатывает все виды профайлера пробоотбора (AQtime, Sleepy, XPerf и т.д.). Как только визуализация указала на оскорбительную функцию (ы), вернитесь к необработанным данным профиля, чтобы лучше понять, какова настоящая причина.

Инструмент gprof2dot генерирует графическое описание точки, которое затем передается в graphviz. Вывод - это, в основном, callgraph с функциями цвета, закодированными их воздействием на приложение. alt text

Несколько подсказок, чтобы получить gprof2dot для создания приятного вывода.

  • Я использую --skew 0.001 на моих графиках, поэтому я могу легко видеть пути горячего кода. В противном случае символ int main() доминирует над графиком.
  • Если вы делаете что-то сумасшедшее с С++-шаблонами, вы, вероятно, захотите добавить --strip. Это особенно верно для Boost.
  • Я использую OProfile для создания моих данных выборки. Чтобы получить хороший результат, мне нужно настроить его для загрузки символов отладки из сторонних и системных библиотек. Не забудьте сделать то же самое, в противном случае вы увидите, что CRT занимает 20% вашего времени приложения, когда действительно происходит malloc уничтожает кучу и едет на 15%.

Ответ 2

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

То, что я делаю в VS, настраивает отображение стека, поэтому он не показывает мне аргументы функции, потому что это делает отображение стека совершенно нечитаемым, IMO.

Затем я беру около 10 образцов, нажимая "паузу" в течение времени, заставляя меня ждать. Я использую ^ A, ^ C и ^ V, чтобы скопировать их в блокнот, для справки. Затем я изучаю каждую из них, чтобы попытаться выяснить, что она в процессе пытается выполнить в то время.

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

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

Примеры видов вещей, которые я нахожу:

  • Во время запуска может быть около 30 слоев в глубину, в процессе попытки извлечь интернационализированные строки символов из ресурсов DLL. Если проверять фактические строки, легко получается, что строки не обязательно должны быть интернационализированы, например, это строки, которые пользователь никогда не видит.

  • При нормальном использовании некоторый код невинно устанавливает свойство Modified в некоторый объект. Этот объект исходит из суперкласса, который фиксирует изменения и вызывает уведомления, которые пульсируют по всей структуре данных, манипулируя пользовательским интерфейсом, создавая и опуская объекты в труднодоступных целях. Это может случиться много - неожиданные последствия уведомлений.

  • Заполнение таблицы по строкам, по ячейке. Оказывается, если вы строите строку сразу, из массива значений, это намного быстрее.

P.S. Если вы многопоточны, когда вы его приостанавливаете, все потоки приостанавливаются. Взгляните на стек вызовов каждого потока. Скорее всего, только один из них является реальным виновником, а остальные бездельничают.

Ответ 3

У меня был некоторый успех с AMD CodeAnalyst.

Ответ 4

У вас есть функция MFC OnIdle? Раньше у меня было приложение практически в реальном времени, которое я должен был исправить, когда падал серийный пакет, когда он был установлен на скорости 19.2K, которую PentiumD должен был не отставать. Функция OnIdle была тем, что убивало вещи. Я не уверен, имеет ли QT эту концепцию, но я тоже проверю это.

Ответ 5

Повторить VS Profiler - если он генерирует такие большие файлы, возможно, ваш интервал выборки слишком частый? Попробуйте опустить его, так как у вас, вероятно, будет достаточно образцов.

И в идеале, убедитесь, что вы не собираете образцы, пока не выполняете проблемную область. Поэтому начните с паузы в сборке, попросите свою программу выполнить "медленную активность", а затем начните сбор. Вам нужно всего 20 секунд сбора. После этого прекратите сбор.

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

Ответ 6

Я успешно использовал PurifyPlus для Windows. Хотя это и не так дешево, IBM предоставляет пробную версию, слегка искалеченную. Все, что вам нужно для профилирования с quantify, являются файлами pdb и связаны с /FIXED: NO. Только недостаток: поддержка Win7/64 не поддерживается.

Ответ 7

Easyprofiler - я еще не видел, чтобы он упоминался здесь, но не уверен, что вы посмотрели на него уже. В том, как он собирает метрические данные, требуется несколько иной подход. Недостатком использования подхода к профилю времени компиляции является необходимость внесения изменений в базу кода. Таким образом, вам нужно будет иметь представление о том, где медленный может быть, и вставьте код профилирования там.

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

Ответ 8

Оформить заказ XPerf

Это бесплатный, неинвазивный и расширяемый профилировщик, предлагаемый MS. Он был разработан Microsoft для профилирования Windows.

Ответ 9

Еще два предложения инструмента.

У Luke Stackwalker есть симпатичное имя (даже если он пытается немного усердно по вкусу), это ничего не будет стоить вам, и вы получите исходный код. Он утверждает, что поддерживает многопоточные программы. Таким образом, это, безусловно, стоит спина.

http://lukestackwalker.sourceforge.net/

Также Glowcode, который я указал мне, стоит использовать:

http://www.glowcode.com/

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

Ответ 10

Если вы подозрительно относитесь к циклу событий, можете переопределить QCoreApplication:: notify() и профилирование вручную dosome (одна или две карты отправители/события в счет/время)?

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

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

Просто идея.

Ответ 11

Изменить: я вижу, что вы упомянули об этом в своем первом посте. Черт возьми, я никогда не думал, что я буду тем парнем.

Вы можете использовать Pin, чтобы скомпоновать ваш код с более тонкой детализацией. Я думаю, что Pin позволит вам создать инструмент для подсчета, сколько раз вы вводите функцию или сколько часов вы тратите там, примерно подражая чему-то вроде VTune или CodeAnalyst. Затем вы можете разбить, какие функции будут задействованы до тех пор, пока ваши проблемы времени не исчезнут.

Ответ 12

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

a) Аналитик AMD Code

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

b) VTune.

  • Он очень хорошо интегрирован в vs2008

  • после того, как вы знаете горячие точки, вам нужно пробовать не только время, но и другие вещи, такие как промахи в кеше и использование памяти. Это очень важно. Настройте сеанс выборки и отредактируйте свойства. Я всегда проверяю время, чтение/запись памяти и пропуски кеша (три разных прогона).

Но больше, чем инструмент, вам нужно получить опыт профилирования. И это означает понимание того, как работает процессор/память/PCI... так что это мой третий вариант

c) Единичное тестирование

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

Мой совет использует случайную выборку в нескольких небольших тестах и ​​пытается стандартизировать стратегию профиля.

Ответ 13

Я только что закончил первую полезную версию CxxProf, портативную ручную библиотеку профилирования для С++.

Он выполняет следующие задачи:

  • Простая интеграция
  • Легко удалить lib во время компиляции
  • Легко удалить lib во время выполнения
  • Поддержка многопоточных приложений
  • Поддержка распределенных систем
  • Сохраняйте влияние на минимум

Эти точки были вырваны из вики проекта, посмотрите там более подробную информацию.

Отказ от ответственности: Im главный разработчик CxxProf

Ответ 14

Я использую xperf/ETW для всех моих профилирующих потребностей. Он имеет крутую кривую обучения, но невероятно мощный. Если вы профилируете Windows, вы должны знать xperf. Я часто использую этот профилировщик, чтобы найти проблемы с производительностью в моем коде и в коде других людей.

В конфигурации, которую я использую:

  • xperf захватывает образцы процессора из каждого ядра, которое выполняет код каждый Миз. Частоту дискретизации можно увеличить до 8 кГц, а образцы включают пользовательский режим и код ядра. Это позволяет выяснить, что thread работает во время работы
  • xperf записывает каждый контекст переключатель (позволяющий совершенную реконструкцию, сколько времени каждый использование потоков), плюс стеки вызовов для включения потоков, плюс стеки вызовов для того, что поток выполнил другой поток, что позволяет отслеживать цепочек ожидания и выяснить, почему поток не работает.
  • Xperf записывает все файлы ввода/вывода из всех процессов.
  • xperf записывает все операции ввода/вывода на диск из всех процессов
  • xperf записывает, какое окно активно, процессор частота, состояние питания ЦП, задержки пользовательского интерфейса и т.д.
  • xperf также может записывать все выделение кучи из одного процесса, все виртуальные распределения из всех процессы и многое другое.

Это много данных, все на одной временной шкале, для всех процессов. Никакой другой профайлер в Windows не может этого сделать.

Я подробно рассказывал о том, как использовать xperf/ETW. Эти сообщения в блогах и некоторые профессионально качественные видеоролики можно найти здесь: http://randomascii.wordpress.com/2014/08/19/etw-training-videos-available-now/

Если вы хотите узнать, что может случиться, если вы не используете xperf, прочитайте эти сообщения в блоге: http://randomascii.wordpress.com/category/investigative-reporting/ Это рассказы о проблемах с производительностью, которые я нашел в коде других людей, которые должны были найти разработчики. Это включает в себя mshtml.dll, загружаемый в компилятор VС++, отказ в обслуживании в встраиваемых файлах VС++, термическое дросселирование на удивительном числе клиентских машин, медленное одношаговое в Visual Studio, выделение 4 ГБ в жестком диске, драйвер диска, ошибка производительности PowerPoint и т.д.

Ответ 15

Просто, чтобы выбросить его, хотя это не полномасштабный профилировщик: если все, что вам нужно, - это зависание циклов событий, которые требуют длительной обработки события, ad-hoc инструмент - это простой вопрос в Qt. Этот подход можно было бы легко расширить, чтобы отслеживать, сколько времени прошло каждое событие для обработки, и каковы были эти события и т.д. Это не универсальный профилировщик, а ориентированный на события цикл.

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

Ответ 16

DevPartner, первоначально разработанный NuMega и теперь распространяемый MicroFocus, когда-то был решением выбора для профилирования и анализа кода (например, утечки памяти и ресурсов). Я не пробовал это недавно, поэтому я не могу заверить вас, что это поможет вам; но у меня были отличные результаты с ним, так что это альтернатива, которую я считаю переустановкой в ​​нашем процессе качества кода (они обеспечивают 14-дневную пробную версию).

Ответ 17

хотя ваш os - win7, программа не может работать под xp? как насчет профиля его под xp, и результат должен быть подсказкой для win7.

Ответ 18

Здесь есть много профилировщиков, и я сам пробовал несколько из них - однако в итоге я написал свои собственные:

http://code.google.com/p/high-performance-cplusplus-profiler/

Конечно, требуется, чтобы вы модифицировали базу кода, но она идеально подходит для сужения узких мест, должна работать на всех x86 (может быть проблема с многоядерными блоками, то есть она использует rdtsc, однако - это чисто для ориентировочное время в любом случае - так что я считаю это достаточным для моих нужд.)