Почему у сводок цикла нет вызывающих абонентов в выводе графика вызовов gprof?

Я использую GNU gprof 2.15.94.0.2.2 для профилирования моей программы на C ++, которая имеет большие циклы вызовов. Я ожидал увидеть что-то подобное ниже в выводе графа вызовов как в документации gprof указано:

index  % time    self  children called     name
----------------------------------------
                 1.77        0    1/1        main [2]
[3]     91.71    1.77        0    1+5    <cycle 1 as a whole> [3]
                 1.02        0    3          b <cycle 1> [4]
                 0.75        0    2          a <cycle 1> [5]
                    0        0    6/6        c [6]
----------------------------------------

Однако ни в одной из моих <cycle as a whole> записей нет списка вызывающих абонентов. Все они такие:

index  % time    self  children called             name
----------------------------------------------
[8]     65.6    259.55  5342.63  9334767+60122608 <cycle 2 as a whole> [8]
                133.28  2051.45  12043564+74015448    foo <cycle 2> [14]
                18.90   976.38   2379645              bar <cycle 2> [21]
...                                                                      
-----------------------------------------------

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

Может ли кто-нибудь сказать мне, почему в выводе отсутствуют вызывающие циклы и как заставить их отображаться?


person an0    schedule 08.05.2009    source источник


Ответы (3)


В вашем приложении используется многопоточность? gprof вообще не работает с потоками. В противном случае вы, скорее всего, столкнулись с ошибкой в ​​gprof. Это устаревшая версия. Лучше использовать что-нибудь вроде oprofile или valgrind.

person Gunther Piez    schedule 24.11.2009

Я собираюсь даже назвать это ошибкой в ​​gprof. Я создал простой пример взаимно рекурсивных функций и получил точно такое же поведение, как и вы. У меня были функции:

int a(int n){return b(n);}
int b(int n){return c(n);}
int c(int n){return (n==0)?n:a(n-1);}

и main ():

for(int j=0; j <1000; ++j)
  for(int i=0; i < 10; ++i)
     cout << a(i);

Я попытался заменить вызов на () на:

int d(int n){return a(n);}

в надежде, что gprof зарегистрирует вызов цикла из d () лучше, чем вызов из main (), но я получил тот же результат.

Я также заменил cout на printf () и создал программу на языке C с теми же результатами: для цикла не было указано ни одного вызывающего абонента.

person Dan Hook    schedule 23.11.2009
comment
Если вы читаете исходный документ gprof, внизу страницы 8 , вы увидите, что авторы не заявляли о большой полезности его обработки рекурсии. - person Mike Dunlavey; 02.11.2011

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

gprof - это то, что есть, но вы можете добиться большего.

person Mike Dunlavey    schedule 23.11.2009