Профили gprof vs cachegrind
При попытке оптимизировать код я немного озадачен различиями в профилях, созданных kcachegrdind
и gprof
. В частности, если я использую gprof (компиляция с помощью переключателя -pg
и т.д.), У меня есть это:
Flat profile:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls ms/call ms/call name
89.62 3.71 3.71 204626 0.02 0.02 objR<true>::R_impl(std::vector<coords_t, std::allocator<coords_t> > const&, std::vector<unsigned long, std::allocator<unsigned long> > const&) const
5.56 3.94 0.23 18018180 0.00 0.00 W2(coords_t const&, coords_t const&)
3.87 4.10 0.16 200202 0.00 0.00 build_matrix(std::vector<coords_t, std::allocator<coords_t> > const&)
0.24 4.11 0.01 400406 0.00 0.00 std::vector<double, std::allocator<double> >::vector(std::vector<double, std::allocator<double> > const&)
0.24 4.12 0.01 100000 0.00 0.00 Wrat(std::vector<coords_t, std::allocator<coords_t> > const&, std::vector<coords_t, std::allocator<coords_t> > const&)
0.24 4.13 0.01 9 1.11 1.11 std::vector<short, std::allocator<short> >* std::__uninitialized_copy_a<__gnu_cxx::__normal_iterator<std::vector<short, std::alloca
Кажется, что мне кажется, что мне не нужно искать нигде, но ::R_impl(...)
В то же время, если я скомпилирую без коммутатора -pg
и запустив valgrind --tool=callgrind ./a.out
вместо этого, у меня есть нечто совсем другое: вот скриншот <<27 > вывода
![enter image description here]()
Если я правильно интерпретирую это, кажется, что ::R_impl(...)
занимает только около 50% времени, а другая половина - в линейной алгебре (Wrat(...)
, eigenvalues
и лежащих в основе вызовов лакетов), которая была ниже в профиле gprof
.
Я понимаю, что gprof
и cachegrind
используют разные методы, и я бы не стал беспокоиться о том, что их результаты несколько отличались. Но здесь это выглядит совсем по-другому, и я теряю информацию о том, как их интерпретировать. Любые идеи или предложения?
Ответы
Ответ 1
Вы смотрите на неправильный столбец. Вы должны посмотреть на второй столбец вывода kcachegrind, который называется "я". Это время, проведенное конкретной подпрограммой, только без учета его детей. Первый столбец имеет кумулятивное время (оно равно 100% машинного времени для основного), и оно не является информативным (на мой взгляд).
Обратите внимание, что из вывода kcachegrind вы можете видеть, что общее время процесса составляет 53,64 секунды, а время, проведенное в подпрограмме "R_impl", составляет 46,72 секунды, что составляет 87% от общего времени. Таким образом, gprof и kcachegrind полностью согласуются.
Ответ 2
gprof
является инструментальным профилировщиком, callgrind
является профилировщиком выборки. С помощью инструментального профилировщика вы получаете накладные расходы для каждой функции ввода и выхода, что может исказить профиль, особенно если у вас есть относительно небольшие функции, которые называются много раз. Пробоотборщики пробоотбора имеют тенденцию быть более точными - они замедляют выполнение всей программы немного, но это имеет тенденцию иметь одинаковый относительный эффект для всех функций.
Попробуйте бесплатную 30-дневную оценку Zoom from RotateRight - я подозреваю, что она даст вам профиль, который больше согласен с callgrind
, чем с gprof
.