Что именно измеряет профилирование C++ (инструменты производительности процессора Google)?

StackOverflow https://stackoverflow.com/questions/1003309

  •  05-07-2019
  •  | 
  •  

Вопрос

Я пытаюсь начать работу с Google Perf Tools для профилирования некоторых приложений, интенсивно использующих процессор.Это статистический расчет, который записывает каждый шаг в файл с использованием ofstream.Я не эксперт по C++, поэтому мне сложно найти узкое место.Мой первый проход дает результаты:

Total: 857 samples
     357  41.7%  41.7%      357  41.7% _write$UNIX2003
     134  15.6%  57.3%      134  15.6% _exp$fenv_access_off
     109  12.7%  70.0%      276  32.2% scythe::dnorm
     103  12.0%  82.0%      103  12.0% _log$fenv_access_off
      58   6.8%  88.8%       58   6.8% scythe::const_matrix_forward_iterator::operator*
      37   4.3%  93.1%       37   4.3% scythe::matrix_forward_iterator::operator*
      15   1.8%  94.9%       47   5.5% std::transform
      13   1.5%  96.4%      486  56.7% SliceStep::DoStep
      10   1.2%  97.5%       10   1.2% 0x0002726c
       5   0.6%  98.1%        5   0.6% 0x000271c7
       5   0.6%  98.7%        5   0.6% _write$NOCANCEL$UNIX2003

Это удивительно, поскольку все реальные вычисления происходят в SliceStep::DoStep.«_write$UNIX2003» (где я могу узнать, что это такое?), похоже, возникает при записи выходного файла.Меня смущает то, что если я закомментирую все outfile << "text" заявлений и запустить ппроф, 95% находится в SliceStep::DoStep и `_write$UNIX2003' исчезнет.Однако мое приложение не ускоряется по общему времени.Все это ускоряется менее чем на 1 процент.

Что мне не хватает?

Добавлен:Вывод pprof без outfile << заявления это:

Total: 790 samples
     205  25.9%  25.9%      205  25.9% _exp$fenv_access_off
     170  21.5%  47.5%      170  21.5% _log$fenv_access_off
     162  20.5%  68.0%      437  55.3% scythe::dnorm
      83  10.5%  78.5%       83  10.5% scythe::const_matrix_forward_iterator::operator*
      70   8.9%  87.3%       70   8.9% scythe::matrix_forward_iterator::operator*
      28   3.5%  90.9%       78   9.9% std::transform
      26   3.3%  94.2%       26   3.3% 0x00027262
      12   1.5%  95.7%       12   1.5% _write$NOCANCEL$UNIX2003
      11   1.4%  97.1%      764  96.7% SliceStep::DoStep
       9   1.1%  98.2%        9   1.1% 0x00027253
       6   0.8%  99.0%        6   0.8% 0x000274a6

Это похоже на то, что я ожидал, за исключением того, что я не вижу видимого увеличения производительности (0,1 секунды при 10-секундном расчете).Код по сути:

ofstream outfile("out.txt");
for loop:
  SliceStep::DoStep()
  outfile << 'result'
outfile.close()

Обновлять:Я рассчитываю время, используя boost::timer, начиная с того места, где начинается профилировщик, и заканчивая там, где он заканчивается.Я не использую нитки или что-то необычное.

Это было полезно?

Решение

Из моих комментариев:

Цифры, которые вы получаете от своего профилировщика, говорят, что без операторов печати программа должна работать примерно на 40% быстрее.

Однако время выполнения остается почти таким же.

Очевидно, что одно из измерений должно быть неправильным.Это означает, что вам придется проводить больше и более качественные измерения.

Сначала я предлагаю начать с другого простого инструмента:команда времени.Это должно дать вам примерное представление о том, на что тратится ваше время.

Если результаты все еще не окончательны, вам нужен лучший тестовый пример:

  • Используйте большую проблему
  • Перед измерением сделайте разминку.Сделайте несколько циклов и затем начните любые измерения (в том же процессе).

Тиристан:Это все в пользователе.Я думаю, то, что я делаю, довольно просто...Означает ли что-нибудь тот факт, что файл все время открыт?

Это означает, что профилировщик ошибается.

Вывод 100000 строк на консоль с помощью Python приводит к чему-то вроде:

for i in xrange(100000):
    print i

Утешить:

time python print.py
[...]
real    0m2.370s
user    0m0.156s
sys     0m0.232s

Против:

time python test.py > /dev/null

real    0m0.133s
user    0m0.116s
sys     0m0.008s

Моя точка зрения такова:Ваши внутренние измерения и время показывает, что вы ничего не получите от отключения вывода.Google Perf Tools говорит, что вам следует это сделать.Кто не прав?

Другие советы

_write$UNIX2003, вероятно, относится к write Системный вызов POSIX, который выводит данные на терминал.Ввод-вывод очень медленный по сравнению с чем-либо еще, поэтому имеет смысл, что ваша программа проводит там много времени, если вы пишете достаточно много вывода.

Я не уверен, почему ваша программа не ускорится, если вы удалите вывод, но я не могу сделать предположение только на основе предоставленной вами информации.Было бы неплохо увидеть часть кода или даже вывод perftools после удаления оператора cout.

Google perftools собирает образцы стека вызовов, поэтому вам нужно получить представление о них.

Согласно документу, вы можете отображать граф вызовов с точностью до оператора или адреса.Это должно сказать вам то, что вам нужно знать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top