Ich habe ein einfaches Sortierprogramm, das ich profile, um einen Fall zu haben, gprof zu studieren; Ich plane später, einen viel größeren Algorithmus zu profilieren.Diskrepanz zwischen Gprof und (Unix) Zeit; gprof meldet niedrigere Laufzeiten
Ich habe mit -pg
kompiliert und lief ./sort die gmon.out
Datei zu produzieren. Wenn ich jedoch gprof ./sort gmon.out
ausführen, sind die Werte, die in kumulativen Sekunden und Selbstsekunden produziert werden, wie ich glaube, nicht genau.
Erstens läuft time(./sort)
ich:
real 0m14.352s
user 0m14.330s
sys 0m0.005s
, die mit meiner Stoppuhr genau ist.
jedoch die gprof Ergebnisse für das flache Profil sind:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls s/call s/call name
56.18 2.76 2.76 1 2.76 4.71 sort(std::vector<int, std::allocator<int> >&)
35.01 4.49 1.72 1870365596 0.00 0.00 std::vector<int, std::allocator<int> >::operator[](unsigned long)
8.96 4.93 0.44 100071 0.00 0.00 std::vector<int, std::allocator<int> >::size() const
0.00 4.93 0.00 50001 0.00 0.00 __gnu_cxx::new_allocator<int>::construct(int*, int const&)
0.00 4.93 0.00 50001 0.00 0.00 void __gnu_cxx::__alloc_traits<std::allocator<int> >::construct<int>(std::allocator<int>&, int*, int const&)
0.00 4.93 0.00 50001 0.00 0.00 std::vector<int, std::allocator<int> >::push_back(int const&)
0.00 4.93 0.00 50001 0.00 0.00 operator new(unsigned long, void*)
0.00 4.93 0.00 170 0.00 0.00 std::_Iter_base<int*, false>::_S_base(int*)
0.00 4.93 0.00 102 0.00 0.00 std::_Niter_base<int*>::iterator_type std::__niter_base<int*>(int*)
0.00 4.93 0.00 68 0.00 0.00 __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >::base() const
0.00 4.93 0.00 68 0.00 0.00 std::_Miter_base<int*>::iterator_type std::__miter_base<int*>(int*)
0.00 4.93 0.00 52 0.00 0.00 std::_Vector_base<int, std::allocator<int> >::_M_get_Tp_allocator()
0.00 4.93 0.00 51 0.00 0.00 __gnu_cxx::new_allocator<int>::max_size() const
0.00 4.93 0.00 34 0.00 0.00 __gnu_cxx::__alloc_traits<std::allocator<int> >::max_size(std::allocator<int> const&)
0.00 4.93 0.00 34 0.00 0.00 __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >::__normal_iterator(int* const&)
0.00 4.93 0.00 34 0.00 0.00 std::_Vector_base<int, std::allocator<int> >::_M_get_Tp_allocator() const
0.00 4.93 0.00 34 0.00 0.00 std::vector<int, std::allocator<int> >::max_size() const
0.00 4.93 0.00 34 0.00 0.00 int* std::__copy_move<false, true, std::random_access_iterator_tag>::__copy_m<int>(int const*, int const*, int*)
0.00 4.93 0.00 34 0.00 0.00 int* std::__uninitialized_copy<true>::__uninit_copy<int*, int*>(int*, int*, int*)
0.00 4.93 0.00 34 0.00 0.00 int* std::__copy_move_a<false, int*, int*>(int*, int*, int*)
0.00 4.93 0.00 34 0.00 0.00 int* std::__copy_move_a2<false, int*, int*>(int*, int*, int*)
0.00 4.93 0.00 34 0.00 0.00 int* std::uninitialized_copy<int*, int*>(int*, int*, int*)
0.00 4.93 0.00 34 0.00 0.00 int* std::__uninitialized_copy_a<int*, int*, int>(int*, int*, int*, std::allocator<int>&)
0.00 4.93 0.00 34 0.00 0.00 int* std::__uninitialized_move_if_noexcept_a<int*, int*, std::allocator<int> >(int*, int*, int*, std::allocator<int>&)
0.00 4.93 0.00 34 0.00 0.00 int* std::copy<int*, int*>(int*, int*, int*)
0.00 4.93 0.00 18 0.00 0.00 void std::_Destroy_aux<true>::__destroy<int*>(int*, int*)
0.00 4.93 0.00 18 0.00 0.00 std::_Vector_base<int, std::allocator<int> >::_M_deallocate(int*, unsigned long)
0.00 4.93 0.00 18 0.00 0.00 void std::_Destroy<int*>(int*, int*)
0.00 4.93 0.00 18 0.00 0.00 void std::_Destroy<int*, int>(int*, int*, std::allocator<int>&)
0.00 4.93 0.00 17 0.00 0.00 __gnu_cxx::new_allocator<int>::deallocate(int*, unsigned long)
0.00 4.93 0.00 17 0.00 0.00 __gnu_cxx::new_allocator<int>::allocate(unsigned long, void const*)
0.00 4.93 0.00 17 0.00 0.00 __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >::difference_type __gnu_cxx::operator-<int*, std::vector<int, std::allocator<int> > >(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > > const&, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > > const&)
0.00 4.93 0.00 17 0.00 0.00 std::vector<int, std::allocator<int> >::_M_check_len(unsigned long, char const*) const
0.00 4.93 0.00 17 0.00 0.00 std::_Vector_base<int, std::allocator<int> >::_M_allocate(unsigned long)
0.00 4.93 0.00 17 0.00 0.00 std::vector<int, std::allocator<int> >::_M_insert_aux(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, int const&)
0.00 4.93 0.00 17 0.00 0.00 std::vector<int, std::allocator<int> >::end()
0.00 4.93 0.00 17 0.00 0.00 std::vector<int, std::allocator<int> >::begin()
0.00 4.93 0.00 17 0.00 0.00 unsigned long const& std::max<unsigned long>(unsigned long const&, unsigned long const&)
0.00 4.93 0.00 2 0.00 0.00 std::operator|(std::_Ios_Openmode, std::_Ios_Openmode)
0.00 4.93 0.00 1 0.00 0.00 _GLOBAL__sub_I_main
0.00 4.93 0.00 1 0.00 0.00 generateData(std::basic_ofstream<char, std::char_traits<char> >&)
0.00 4.93 0.00 1 0.00 0.22 writeSortedFile(std::vector<int, std::allocator<int> >&)
0.00 4.93 0.00 1 0.00 0.00 __static_initialization_and_destruction_0(int, int)
0.00 4.93 0.00 1 0.00 0.00 loadBuf(std::vector<int, std::allocator<int> >&, std::basic_ifstream<char, std::char_traits<char> >&)
0.00 4.93 0.00 1 0.00 0.00 __gnu_cxx::new_allocator<int>::new_allocator()
0.00 4.93 0.00 1 0.00 0.00 __gnu_cxx::new_allocator<int>::~new_allocator()
0.00 4.93 0.00 1 0.00 0.00 std::allocator<int>::allocator()
0.00 4.93 0.00 1 0.00 0.00 std::allocator<int>::~allocator()
0.00 4.93 0.00 1 0.00 0.00 std::_Vector_base<int, std::allocator<int> >::_Vector_impl::_Vector_impl()
0.00 4.93 0.00 1 0.00 0.00 std::_Vector_base<int, std::allocator<int> >::_Vector_impl::~_Vector_impl()
0.00 4.93 0.00 1 0.00 0.00 std::_Vector_base<int, std::allocator<int> >::_Vector_base()
0.00 4.93 0.00 1 0.00 0.00 std::_Vector_base<int, std::allocator<int> >::~_Vector_base()
0.00 4.93 0.00 1 0.00 0.00 std::vector<int, std::allocator<int> >::vector()
0.00 4.93 0.00 1 0.00 0.00 std::vector<int, std::allocator<int> >::~vector()
So werden die kumulierten Sekunden sammeln sich nicht auf den wahren Wert (~ 14s), so scheint es. Die Ergebnisse zeigen, dass sort()
am teuersten ist, aber die tatsächlichen Zeitwerte addieren sich nicht. -z
ändert dies nicht, aber das ist zu erwarten. Das Call Graph (nicht im Lieferumfang enthalten), scheint nichts zu zeigen, wo die fehlenden Sekunden sind; d. h. die zusätzlichen Sekunden sind nicht in Kindern.
Ich scheine ähnliche Ergebnisse zu erhalten (wo gprof viel kleinere Zeitwerte als erwartet gibt), wenn ich versuche und meinen größeren Algorithmus profiliere, den ich oben erwähne - gprof sagt die Laufzeit ist ~ 450s, wo es tatsächlich über 3 Stunden dauert. Ich dachte, dies sei darauf zurückzuführen, dass gprof nicht in der Lage ist, mit MPI umzugehen, was der größere Algorithmus ausgiebig nutzt, aber jetzt denke ich, dass ich die gprof-Ergebnisse entweder falsch interpretiere oder mir einige Flags vermisse.
Ist es möglich, dass ich meine gmon.out
Datei nicht wirklich in Betracht ziehe? Der Grund, warum ich das denke ist, dass, wenn ich gprof ./sort
laufen lasse ich die exakt gleichen Ergebnisse wie gprof ./sort gmon.out
bekomme. Daher scheint es, als ob es nicht einmal gmon.out
verwendet. Ich dachte, gmon.out
wurde in Verbindung mit der ausführbaren Datei benötigt, um Zeit auf Funktionen abzubilden. Wie kann gprof eine Ausgabe ohne gmon.out
erzeugen?
Jede aufschlussreiche Information ist mehr als willkommen, danke im Voraus!
HINWEIS: lesen rund um, z. B. (this post), fand ich Informationen, die darauf hindeutet, dass Gprof Probleme mit der Analyse Heap Zuordnung usw. (new
) hat. Ich sollte beachten, dass ./sort
std::vector
verwendet, um Elemente zu halten, die Heap zugeordnet werden. Bitte lassen Sie mich wissen, wenn dies ein mögliches Problem ist.
Studieren gprof? Ich habe ein paar Lektüre für Sie: [* this, *] (http://stackoverflow.com/a/1779343/23771) [* this, *] (http://stackoverflow.com/a/25870103/23771) und [* this, *] (http://stackoverflow.com/a/27867426/23771) für Anfänger. –