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
std::rand
, которая не была скомпилирована с -g, не так ли? Таким образом, в вашем коде практически не будет образцов. - person Mike Dunlavey   schedule 27.12.2017