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

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

кроме того, как точно выполняется синхронизация?

2 ответов


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

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

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

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


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

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

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

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

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

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

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

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