Что именно измеряет профилирование C++ (google cpu perf tools)?
Я пытаюсь начать работу с Google Perf Tools для профилирования некоторых приложений, интенсивно использующих процессор. Это статистический расчет, который выводит каждый шаг в файл, используя `ofstream'. Я не эксперт по C++, поэтому мне трудно найти узкое место. Мой первый проход дает результаты:
Всего: 857 образцов 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% косы:: dnorm 103 12,0% 82,0% 103 12,0% _log$fenv_access_off 58 6,8% 88,8% 58 6,8% косы::const_matrix_forward_iterator::operator* 37 4,3% 93,1% 37 4,3% косы::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"
заявления и запустить pprof, 95% находится в SliceStep::DoStep
и `_write$UNIX2003'исчезает. Тем не менее, мое приложение не ускоряется, если судить по общему времени. Все это ускоряется менее чем на 1 процент.
Что мне не хватает?
Добавлено: вывод pprof без outfile <<
заявления это:
Всего: 790 образцов 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% косу:: dnorm 83 10,5% 78,5% 83 10,5% косу:: const_matrix_forward_iterator:: оператор * 70 8,9% 87,3% 70 8,9% косы::matrix_forward_iterator::operator* 28 3,5% 90,9% 78 9,9% std:: трансформация 26 3,3% 94,2% 26 3,3% 0x00027262 12 1,5% 95,7% 12 1,5% _ писать $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, начиная с начала профилировщика и заканчивая там, где он заканчивается. Я не использую темы или что-нибудь необычное.
3 ответа
Из моих комментариев:
Цифры, которые вы получаете от своего профилировщика, говорят, что программа должна быть примерно на 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 говорит, что вы должны. Кто не прав?
Google perftools собирает образцы стека вызовов, поэтому вам нужно немного разобраться в них.
В соответствии с документом, вы можете отобразить график вызовов в выписке или детализации адреса. Это должно сказать вам, что вам нужно знать.
_write$UNIX2003, вероятно, относится к write
Системный вызов POSIX, который выводит на терминал. Ввод / вывод очень медленный по сравнению с чем-либо еще, поэтому имеет смысл, что ваша программа тратит там много времени, если вы пишете довольно много информации.
Я не уверен, почему ваша программа не будет ускоряться, когда вы удаляете вывод, но я не могу точно догадаться только о той информации, которую вы предоставили. Было бы неплохо увидеть некоторый код или даже вывод perftools после удаления оператора cout.