Какой инструмент профилирования наиболее надежный gprof или kcachegrind?

StackOverflow https://stackoverflow.com/questions/6328673

Вопрос

Профилирование некоторого кода для обработки чисел на C ++ с помощью обоих gprof и kcachegrind выдает аналогичные результаты для функций, которые вносят наибольший вклад во время выполнения (50-80% в зависимости от входных данных), но для функций в пределах 10-30% оба этих инструмента дают разные результаты.Означает ли это, что один из них ненадежен?Что бы ты здесь сделал?

Это было полезно?

Решение

gprof ( гпроф ) на самом деле это довольно примитивно.Вот что это делает.1) Он производит выборку программного счетчика с постоянной скоростью и записывает, сколько выборок было получено в каждой функции (исключительное время).2) Подсчитывается, сколько раз любая функция A вызывает любую функцию B.Исходя из этого, он может узнать, сколько раз в общей сложности вызывалась каждая функция и каково было ее среднее эксклюзивное время.Чтобы получить среднее инклюзивное время каждой функции, она увеличивает эксклюзивное время вверх по графику вызовов.

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

Позвоните в Grind может работать на уровне линий - это хорошо.К сожалению, у него есть и другие проблемы.

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

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

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

Что случилось бы с этими образцами?

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

Я не хочу вдаваться в излишнюю статистику, но многие люди думают, что вам нужно много выборок, потому что они считают, что точность измерения важна.Это не так, если причина, по которой вы делаете это, заключается в том, чтобы выяснить, что исправить, чтобы ускорить работу.Акцент делается на нахождение что исправить, а не на измерение IT.Строка L находится в стеке какую-то долю F времени, верно?Таким образом, у каждого образца есть вероятность F попадания в него, верно?Точно так же, как подбрасывать монетку.Существует теория этого, называемая Правило наследования.В нем говорится, что (при упрощающих, но общих предположениях), если вы подбросите монету N раз и увидите "орел" S раз, вы можете оценить честность монеты F как (в среднем) (S+1)/(N+2).Итак, если вы возьмете как можно меньше три образцы, и смотрите L на два из них знаете ли вы, что такое F? Конечно, нет. Но ты делай знаю, что в среднем это (2+1)/(3+2) или 60%.Итак, вот сколько времени вы могли бы сэкономить (в среднем), "оптимизировав" строку L.И, конечно же, образцы стека показали вам именно так где находится строка L ("узкое место"**).Действительно ли имело значение, что вы не измерили его с точностью до двух или трех знаков после запятой?

Кстати, он невосприимчив к все остальные проблемы, упомянутые выше.

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

Другие советы

gprofвременные данные являются статистическими (читайте об этом в детали профилирования документы).

С другой стороны, KCacheGrind использование valgrind который фактически интерпретирует весь код.

Итак KCacheGrind может быть "более точным" (за счет больших накладных расходов) если процессор , смоделированный valgrind близок к вашему реальному процессору.

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

Для "лучшего" gprof данных, запускайте свой код дольше (и на как можно более широком диапазоне тестовых данных).Чем больше у вас данных, тем лучше будут результаты измерений статистически.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top