За пределами выборки стека: C ++ Profilers - PullRequest
141 голосов
/ 09 декабря 2010

История хакера

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

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

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

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

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

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

  • XPerf:
  • Glowcode:
  • Девпартнер:

Примечания: Среда Intel на данный момент. VS2008, буст библиотеки. Qt 4+. И жалкий скандал всех их: интеграция Qt / MFC через trolltech. <Ч /> Сейчас: Спустя почти две недели, похоже, моя проблема решена. Благодаря множеству инструментов, включая почти все в списке и пару моих личных приемов, мы нашли основные узкие места. Тем не менее, я собираюсь продолжать тестировать, исследовать и опробовать новые профилировщики, а также новые технологии. Зачем? Потому что я в долгу перед вами, ребята, потому что вы, ребята, молодцы. Это немного замедляет сроки, но я все еще очень рад продолжать пробовать новые инструменты.

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

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

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

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

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

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

Ответы [ 19 ]

61 голосов
/ 15 декабря 2010

Первое:

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

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

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

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

Секунда:

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

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

Несколько советов, чтобы gprof2dot генерировал хороший вывод.

  • Я использую --skew из 0,001 на своих графиках, чтобы я мог легко видеть горячие пути кода.В противном случае int main() доминирует на графике.
  • Если вы делаете что-то сумасшедшее с шаблонами C ++, вы, вероятно, захотите добавить --strip.Это особенно верно для Boost.
  • Я использую OProfile для генерации данных выборки.Чтобы получить хороший вывод, мне нужно настроить его для загрузки символов отладки из сторонних и системных библиотек.Обязательно сделайте то же самое, в противном случае вы увидите, что CRT отнимает 20% времени вашего приложения, тогда как на самом деле malloc уничтожает кучу и съедает 15%.
15 голосов
/ 09 декабря 2010

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

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

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

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

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

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

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

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

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

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

8 голосов
/ 09 декабря 2010

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

7 голосов
/ 12 декабря 2010

Есть ли у вас функция MFC OnIdle? Раньше у меня было приложение, работающее почти в реальном времени, которое мне приходилось исправлять, которое сбрасывало последовательные пакеты при скорости 19,2 КБ, с которой PentiumD мог справиться. Функция OnIdle была тем, что убивало вещи. Я не уверен, что QT имеет такую ​​концепцию, но я бы тоже это проверил.

4 голосов
/ 14 декабря 2010

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

4 голосов
/ 09 декабря 2010

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

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

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

3 голосов
/ 11 декабря 2010

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

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

3 голосов
/ 13 декабря 2010

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

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

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

Просто идея.

3 голосов
/ 12 декабря 2010

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

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

http://lukestackwalker.sourceforge.net/

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

http://www.glowcode.com/

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

3 голосов
/ 12 декабря 2010

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

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

...