Я пытаюсь выполнить профилирование производительности на плохо поддерживаемой прототипе встроенной платформы.
Я отмечаю, что флаг GCC -pg заставляет thunks __gnu_mcount_nc
вставляться при входе в каждую функцию. Реализация __gnu_mcount_nc
недоступна (и поставщик не заинтересован в помощи), однако, поскольку тривиально написать тот, который просто записывает кадр стека и текущий цикл цикла, я сделал это; это отлично работает и дает полезные результаты с точки зрения графиков звонящего/вызываемого абонента и наиболее часто называемых функций.
Мне бы очень хотелось получить информацию о времени, проведенном в функциональных телах, однако мне трудно понять, как подойти к этому только с записью, но не с выходом, к каждой функции, зацепляемой: вы можете точно сказать когда каждая функция вводится, но не зацепив точки выхода, вы не можете знать, сколько времени вы получите, чтобы получить следующую информацию, чтобы атрибут вызываемого абонента и сколько для вызывающих.
Тем не менее, инструменты профилирования GNU на самом деле явно способны собирать информацию о времени выполнения для функций на многих платформах, поэтому, по-видимому, разработчики имеют определенную схему для достижения этой цели.
Я видел некоторые существующие реализации, которые выполняют такие вещи, как сохранение теневого вызова и сворачивание обратного адреса при входе в __gnu_mcount_nc, так что __gnu_mcount_nc снова будет вызван, когда вызываемый возвращает; он может затем сопоставить триллелет caller/callee/sp с верхней частью теневого вызова и таким образом отличить этот случай от записи вызова, записать время выхода и правильно вернуться к вызывающему.
Этот подход оставляет желать лучшего:
- похоже, что он может быть хрупким при наличии рекурсии и библиотек, скомпилированных без флага -pg
- кажется, что было бы сложно реализовать с небольшими накладными расходами или вообще во встроенных многопоточных/многоядерных средах, где поддержка TLS на основе инструментария отсутствует, а текущий идентификатор потока может быть дорогостоящим/сложным, чтобы получить
Есть ли какой-то очевидный лучший способ реализовать __gnu_mcount_nc, чтобы сборка -pg могла захватывать выход функции, а также время входа, которое мне не хватает?