Как именно работает gprof?

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

Кроме того, как именно рассчитывается время?


person Alex    schedule 12.02.2011    source источник


Ответы (2)


Что ж, это дает хорошее объяснение. Также здесь объясняется статистическое профилирование.

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

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

Gprof делает и то, и другое. Он инструментирует код и собирает образцы, глядя на счетчик программы.

person Dr G    schedule 12.02.2011
comment
Разве ему не пришлось бы ползать вверх по стеку, чтобы получить надежные следы? - person Alex; 13.02.2011
comment
@Alex: Тот факт, что этого не произошло, является одной из его основных проблем. - person Mike Dunlavey; 13.02.2011

Просто прочитав статью (снова), позвольте мне попробовать чтобы объяснить это.

Предположим, он берет образцы на частоте 100 Гц, за исключением случаев, когда процесс заблокирован для ввода-вывода или по какой-либо другой причине. Каждый образец записывает ПК, который выполняет какую-либо функцию. Счетчик выборок в этой функции увеличивается.

Итак, в конце прогона, если было (скажем) 1000 выборок, это означает, что общее время выполнения (только для ЦП) составило 10 секунд. Если подпрограмма B записала, скажем, 500 из этих выборок, это означает, что ее общее время выполнения составляет 1/2 от общего количества, или 5 секунд. Это его собственное время, потому что в нем находится ПК. Это не говорит о том, сколько времени в среднем занимает выполнение. Чтобы это сказать, вам нужно знать, сколько раз он был вызван. Также сюда не входит время, проведенное в вызываемых абонентах.

Когда код компилируется с флагом -pg, в код входа каждой подпрограммы вставляется специальный вызов. Это замечает, что введена процедура B, и замечает, что она вызывается с места вызова в подпрограмме A. Существует таблица, проиндексированная этим участком вызова, где этот вызов может быть подсчитан. В конце концов, gprof может сказать, сколько раз B был вызван в целом, и сколько из них было из A.

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

Чтобы получить общее кумулятивное время (собственное плюс вызываемые) подпрограммы A, gprof требуется собственное время A плюс общее количество вызовов каждой подчиненной подпрограммы B, умноженное на среднее совокупное время B. разделенное на общее количество вызовов A, чтобы получить среднее суммарное время A.

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

Все это очень умно и, как отмечают авторы, полно оговорок.

person Mike Dunlavey    schedule 18.02.2011
comment
привет, в чем разница между этой опцией и опцией -finstrument-functions? - person Elinx; 16.01.2017
comment
@elinx: -finstrument-functions - это параметр gcc (не gprof), который позволяет вам помещать функции входа и выхода, которые вы пишете, в каждую подпрограмму, обрабатываемую компилятором. Он дает вам только адреса вызывающего и вызываемого, поэтому вам нужно выполнить некоторую пост-обработку. Если вы хотите рассчитать время, вы должны выяснить, как это сделать. Это далеко от диагностики проблем с производительностью. Я показываю простой способ сделать это в этом коротком видео < / а>. - person Mike Dunlavey; 16.01.2017