gprof не выводит

Я пытаюсь использовать gprof для профилирования разрабатываемого мной числового кода, но gprof, похоже, не может собирать данные из моей программы. Вот моя командная строка:

g++ -Wall -O3 -g -pg -o fftw_test fftw_test.cpp -lfftw3 -lfftw3_threads -lm && ./fftw_test

Файл gmon.out создан, но, похоже, в нем нет данных. Когда я бегу

gprof -b fftw_test gmon.out > gprof.out

Все, что я получаю, это

Flat profile:

Each sample counts as 0.01 seconds.
  %   cumulative   self              self     total           
 time   seconds   seconds    calls  Ts/call  Ts/call  name    


                        Call graph


granularity: each sample hit covers 2 byte(s) no time propagated

index % time    self  children    called     name


Index by function name

Есть идеи?

Код делает много всего, он не просто вызывает процедуры FFTW. В нем есть функции, которые вычисляют определенные комплексные коэффициенты, функции, которые умножают входные данные на эти коэффициенты, и так далее.

Изменить: включая пример кода и результаты.

#include <cstdlib>
#include <ctime>

int main()
{
   std::srand( std::time( 0 ) );

   double sum = 0.0;

   for ( int i = 0; i < RAND_MAX; ++i )
      sum += std::rand() / ( double ) RAND_MAX;

   std::cout << sum << '\n';

   return 0;
}

Командные строки:

$ g++ -Wall -O3 -g -pg -o gprof_test gprof_test.cpp && ./gprof_test
1.07374e+09
$ gprof -b gprof_test gmon.out > gprof.out
$ cat gprof.out

Результат:

Flat profile:

Each sample counts as 0.01 seconds.
 no time accumulated

  %   cumulative   self              self     total           
 time   seconds   seconds    calls  Ts/call  Ts/call  name    


                        Call graph


granularity: each sample hit covers 2 byte(s) no time propagated

index % time    self  children    called     name


Index by function name

И это все.


person Elias    schedule 08.10.2017    source источник
comment
Ни единого взаимодействия? Что ж, я пробовал инструменты perf для Linux, и они, кажется, неплохо справляются со своей задачей, но интерпретировать результат непросто. Я придумал свой собственный класс профилировщика для бедняков, чтобы помочь мне с работой, и в итоге значительно сократил время вычислений.   -  person Elias    schedule 09.10.2017
comment
Элиас, это странно. Майк stackoverflow.com/users/23771/mike-dunlavey обычно рекомендует свой непатентованный статистически подтвержденный GDB 5 случайных обратных трассировок. бедняк, профилирующий почти в каждом вопросе с меткой [профилирование]. Может у вас гпроф сломан, что за ОС? Можете ли вы создать (или найти в примерах fftw lib) более простой вариант программы, которая будет заполнять некоторые данные и вызывать fftw с пустым отчетом gprof, чтобы мы могли проверить ваш случай?   -  person osgx    schedule 25.10.2017
comment
У меня такая же проблема с простой основной программой. gcc 7.2.0 gprof 2.29.1 для Archlinux. Это похоже на несовместимое.   -  person Isaac Pascual    schedule 02.11.2017
comment
@IsaacPascual, не могли бы вы выложить в Интернете пример программы, в которой возникла проблема? В вашей программе много вычислений с fttw или она слишком короткая?   -  person osgx    schedule 17.12.2017
comment
Ваша программа собирается потратить 100% минус эпсилон своего времени на функцию std::rand, которая не была скомпилирована с -g, не так ли? Таким образом, в вашем коде практически не будет образцов.   -  person Mike Dunlavey    schedule 27.12.2017


Ответы (2)


Если вы используете gcc 6, вы, скорее всего, столкнетесь с эта ошибка (обратите внимание, что ошибка не специфична для Debian, а зависит от того, как был собран gcc). Обходной путь - просто скомпилировать с использованием опции `-no-pie ', которая отключает создание независимого от позиции кода.

Это хорошее начало, если вы хотите узнать больше о PIE.

person jaymmer - Reinstate Monica    schedule 07.08.2018

gprof, похоже, не может собирать данные из моей программы. Вот моя командная строка:

g++ -Wall -O3 -g -pg -o fftw_test fftw_test.cpp -lfftw3 -lfftw3_threads -lm && ./fftw_test

Ваша программа использует библиотеку fftw и, вероятно, состоит почти только из вызовов библиотеки fftw. Какое время работы? Ваша программа может быть слишком быстрой для профилирования с помощью gprof. Обновление. И библиотека gprof может быть не видна, поскольку она была скомпилирована без включения профилирования gprof.

GNU gprof состоит из двух частей. Во-первых, он обрабатывает вызовы функций в файлах c / cpp, которые были скомпилированы с параметром -pg (с вызовами функций mcount - https://en.wikipedia.org/wiki/Gprof) - чтобы получить информацию о вызывающем / вызываемом абоненте. Во-вторых, он связывает дополнительную библиотеку профилирования с вашим исполняемым файлом, чтобы добавить периодическую выборку, чтобы определить, какой код выполнялся дольше. Отбор проб производится с помощью профиля (сетитимера). Профилирование установщика имеет ограниченное разрешение и не может разрешать интервалы менее 10 мс или 1 мс (100 или 1000 выборок в секунду).

И в вашем примере библиотека fftw, вероятно, была скомпилирована без инструментовки, поэтому в ней не было mcount вызовов. Его все еще можно захватить с помощью выборочной части, но только для основного потока программы (https://en.wikipedia.org/wiki/Gprof - «обычно это профилирует только основной поток приложения»).

Профилировщик perf не имеет инструментария с mcount (он получает вызываемого / вызывающего из разматывания стека при записи с параметром -g), но у него гораздо лучшие варианты статистики / выборки (он может использовать аппаратные счетчики PMU), без ограничения 100 или 1000 Гц, и он поддерживает (профилирует) резьбу правильно. Попробуйте perf record -F1000 ./fftw_test (с частотой дискретизации 1 кГц) и perf report или perf report > report.txt. Также есть несколько интерфейсов GUI / HTML для выполнения: https://github.com/KDAB/hotspot https://github.com/jrfonseca/gprof2dot

Для лучшего профилировщика стиля setitimer проверьте https://github.com/gperftools/gperftools для " ПРОФИЛЕР ЦП ".

======

С вашим тестом у меня есть некоторые результаты gprof на машине Debian 8.6 Linux версии 3.16.0-4-amd64 x86_64, g ++ (Debian 4.9.2-10), gprof - это "GNU gprof (GNU Binutils для Debian) 2.27"

$ cat gprof_test.cpp
#include <cstdlib>
#include <ctime>
#include <iostream>
int main()
{
   std::srand( std::time( 0 ) );
   double sum = 0.0;
   for ( int i = 0; i < 100000000; ++i )
      sum += std::rand() / ( double ) RAND_MAX;
   std::cout << sum << '\n';
   return 0;
}
$ g++ -Wall -O3 -g -pg -o gprof_test gprof_test.cpp && time ./gprof_test
5.00069e+06
real    0m0.992s
$ gprof -b gprof_test gmon.out
Flat profile:

Each sample counts as 0.01 seconds.
 no time accumulated

  %   cumulative   self              self     total
 time   seconds   seconds    calls  Ts/call  Ts/call  name
  0.00      0.00     0.00        1     0.00     0.00  _GLOBAL__sub_I_main

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

$ cat *cpp
#include <cstdlib>
#include <ctime>
#include <iostream>

int rand_wrapper1()
{
  return std::rand();
}
int rand_scale1()
{
  return rand_wrapper1() / ( double ) RAND_MAX;
}
int main()
{
   std::srand( std::time( 0 ) );
   double sum = 0.0;
   for ( int i = 0; i < 100000000; ++i )
    sum+= rand_scale1();
//      sum += std::rand() / ( double ) RAND_MAX;
   std::cout << sum << '\n';
   return 0;
}
$ g++ -Wall -O3 -fno-inline -g -pg -o gprof_test gprof_test.cpp && time ./gprof_test
real    0m2.345s
$ gprof -b gprof_test gmon.out
Flat profile:

Each sample counts as 0.01 seconds.
  %   cumulative   self              self     total
 time   seconds   seconds    calls  ns/call  ns/call  name
 80.02      0.57     0.57                             rand_scale1()
 19.29      0.71     0.14 100000000     1.37     1.37  rand_wrapper1()
  2.14      0.72     0.02                             frame_dummy
  0.00      0.72     0.00        1     0.00     0.00  _GLOBAL__sub_I__Z13rand_wrapper1v
  0.00      0.72     0.00        1     0.00     0.00  __static_initialization_and_destruction_0(int, int) [clone .constprop.0]


                        Call graph


granularity: each sample hit covers 2 byte(s) for 1.39% of 0.72 seconds

index % time    self  children    called     name
                                                 <spontaneous>
[1]     97.9    0.57    0.14                 rand_scale1() [1]
                0.14    0.00 100000000/100000000     rand_wrapper1() [2]
-----------------------------------------------
                0.14    0.00 100000000/100000000     rand_scale1() [1]
[2]     19.0    0.14    0.00 100000000         rand_wrapper1() [2]

И perf видит все части:

$ perf record ./gprof_test
0
[ perf record: Woken up 2 times to write data ]
[ perf record: Captured and wrote 0.388 MB perf.data (~16954 samples) ]
$ perf report |more   
# Samples: 9K of event 'cycles'
# Event count (approx.): 7373484231
#
# Overhead     Command      Shared Object                     Symbol
# ........  ..........  .................  .........................
#
    25.91%  gprof_test  gprof_test         [.] rand_scale1()
    21.65%  gprof_test  libc-2.19.so       [.] __mcount_internal
    13.88%  gprof_test  libc-2.19.so       [.] _mcount
    12.54%  gprof_test  gprof_test         [.] main
     9.35%  gprof_test  libc-2.19.so       [.] __random_r
     8.40%  gprof_test  libc-2.19.so       [.] __random
     3.97%  gprof_test  gprof_test         [.] rand_wrapper1()
     2.79%  gprof_test  libc-2.19.so       [.] rand
     1.41%  gprof_test  gprof_test         [.] mcount@plt
     0.03%  gprof_test  [kernel.kallsyms]  [k] memset
person osgx    schedule 25.10.2017
comment
Это не то. У меня такое же поведение с программой, которая запускает большой цикл. - person Elias; 16.12.2017
comment
Элиас, не могли бы вы выложить в Интернете пример программы, в которой возникла проблема (с инструкциями по сборке?) - person osgx; 17.12.2017
comment
Я отредактировал вопрос. Если у вас есть какой-то конкретный пример кода, который вы хотите, чтобы я запустил, я с удовольствием его сделаю. - person Elias; 26.12.2017
comment
Элиас, спасибо, через несколько дней протестирую код. Можете ли вы также дать несколько подсказок о вашей платформе, это Linux или BSD или macos и версия ОС (например, uname -a вывод с удаленным реальным именем хоста)? Версии g ++ и gprof? - person osgx; 27.12.2017