профилирование — профилировщик для кода C ++, очень сонный

Я новичок с профилированием. Я хотел бы оптимизировать мой код для удовлетворения временных ограничений. Я использую Visual C ++ 08 Express и, следовательно, мне пришлось скачать профилировщик, для меня это очень сонно. Я немного искал, но не нашел приличного учебника по Sleepy, и вот мой вопрос:
Как правильно его использовать? Я понял общую идею профилирования, поэтому отсортировал по% exclusive, чтобы найти свои узкие места. Во-первых, в верхней части этого списка у меня есть ZwWaitForSingleObject, RtlEnterCriticalSection, оператор новый, RtlLeaveCriticalSection, Printf, некоторые итераторы … и после того, как они принимают примерно 60%, приходит моя первая функция, первая позиция с дочерними вызовами. Может кто-нибудь объяснить мне, почему вышеперечисленное выходит, что они означают и как я могу оптимизировать свой код, если у меня нет доступа к этим критическим 60%? (для «исходного файла»: неизвестно …).
Кроме того, для моей функции я думаю, что у меня есть время для каждой строки, но это не так, например. арифметика или некоторые функции не имеют времени (не вложены в неиспользуемые предложения «если»).
И последнее: как узнать, что какая-то строка может выполняться сверхбыстро, но вызывается тысячи раз, являясь фактическим узким местом?

И наконец, хорош ли Сонный? Или какая-то бесплатная альтернатива для моей платформы?

Помощь очень ценится!
ура!

        • ОБНОВИТЬ — — — — —

Я нашел другую версию профилировщика, названную простой Sleepy. Он показывает, сколько раз был вызван какой-то фрагмент, плюс номер строки (я думаю, это указывает на критический). Так в моем случае .. KiFastSystemCallRet принимает 50%! Это означает, что он ждет каких-то данных, верно? Как улучшить этот вопрос, может быть, есть достойный подход, чтобы отследить, что вызывает эти множественные вызовы и в конечном итоге удалить / изменить его?

4

Решение

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

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

Есть мнение меньшинства, и единственное, что он должен рекомендовать, это фактические значимые результаты (плюс железная теория).

Если у вас есть «узкое место» (а у вас, вероятно, несколько), это займет некоторую долю времени, например, 30%.
Просто отнеситесь к этому как к ошибке, которую можно найти.

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

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

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

Есть много литературы о профилировании, но очень мало, что на самом деле говорит о том, насколько быстро это достигается на практике.
Вот конкретный пример с ускорением почти на 3 порядка.

5

Другие решения

Я использовал GlowCode (коммерческий продукт, похожий на Sleepy) для профилирования нативного кода C ++. Вы запускаете процесс инструментирования, затем выполняете свою программу, затем смотрите на данные, полученные инструментом. Шаг инструментирования вводит небольшую функцию трассировки в точки входа и выхода каждого метода и просто измеряет, сколько времени требуется для выполнения каждой функции до завершения.

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

Если вы сортируете по «наиболее часто вызываемым» по «наименее вызываемым», вы можете увидеть некоторые из крошечных функций, которые вызываются повсюду (итерационные методы, такие как next()и т. д.) Нужно убедиться, что наиболее часто вызываемые функции действительно чистые. Сохранение миллисекунды в процедуре, называемой 500 раз, для рисования экрана ускорит этот экран на полсекунды. Это поможет вам решить, какие из них наиболее важны для ваших усилий.

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

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

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

Точно так же, экономя одну миллисекунду от сервиса, который обрабатывает 100 пользователей в секунду, вы получите улучшение на 10%, что означает, что вы могли бы улучшить сервис для обработки 110 пользователей в секунду.

Причиной для беспокойства является то, что кодирование изменяется строго для повышения производительности, часто отрицательно влияя на структуру вашего кода, добавляя сложность. Допустим, вы решили улучшить обращение к базе данных, кэшируя результаты. Как вы узнаете, когда кеш становится недействительным? Вы добавляете механизм очистки кэша? Рассмотрим финансовую транзакцию, в которой цикл по всем позициям для получения промежуточного итога является медленным, поэтому вы решаете сохранить накопитель runningTotal для более быстрого ответа. Теперь вам нужно изменить runningTotal для всех видов ситуаций, таких как пустоты строк, развороты, удаления, модификации, изменения количества и т. Д. Это делает код более сложным и более подверженным ошибкам.

2

По вопросам рекламы [email protected]