Профили 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.