Подтвердить что ты не робот

Профилирование С++ при наличии агрессивной вставки?

Я пытаюсь выяснить, где моя программа на С++ тратит свое время, используя gprof. Вот моя дилемма: если я компилирую с теми же настройками оптимизации, которые я использую для своей сборки релиза, почти все становится вложенным, и gprof говорит мне, бесполезно, что 90% моего времени проводится в основной рутине, где все было встроено. С другой стороны, если я компилирую с отключенной вставкой, программа работает на порядок медленнее.

Я хочу узнать, сколько процедур времени вызывается из моей основной подпрограммы, когда моя программа скомпилирована с включенной вставкой.

Я запускаю 64-разрядный Ubuntu 9.04 на четырехъядерном процессоре Intel. Я заглянул в google-perftools, но на x86_64 это плохо работает. Работа на 32-битной машине не является вариантом.

Есть ли у кого-нибудь предложения относительно того, как я могу более эффективно профилировать мое приложение, когда включена вставка?

Изменить: Вот некоторые пояснения к моей проблеме. Прошу прощения, если сначала не было ясно.

Я хочу найти, где время проводилось в моем приложении. Профилирование моей оптимизированной сборки привело к тому, что gprof сказал мне, что ~ 90% времени проводится в основном, где все было встроено. Я уже знал это перед профилированием!

Я хочу узнать, сколько времени выполняются встроенными функциями, желательно, не отключая оптимизацию или встраивание в мои варианты сборки. Приложение на порядок медленнее при профилировании с отключением вложения. Эта разница во времени исполнения является проблемой удобства, но также я не уверен, что профиль производительности программы, построенной с отключенной вставкой, будет сильно соответствовать профилю производительности программы, построенной с включенной встраиванием.

Короче: есть ли способ получить полезную информацию о профилировании на С++-программе без отключения оптимизации или вложения?

4b9b3361

Ответ 1

Я предполагаю, что вы хотите, чтобы выяснить, какие строки кода стоят вам достаточно, чтобы их можно было оптимизировать. Это сильно отличается от функций синхронизации. Вы можете сделать лучше, чем gprof.

Здесь достаточно полное объяснение того, как это сделать.

Вы можете сделать это вручную или использовать один из профилировщиков, которые могут предоставить такую ​​же информацию, как oprofile, и RotateRight/Zoom.

BTW, вложение имеет важное значение только в том случае, если подпрограммы, являющиеся встроенными, являются маленькими и сами не вызывают функции, и если строки, в которых они вызывается, достаточно активны, чтобы время было значительным.

Что касается порядка величины отношения производительности между сборкой debug и release, это может быть связано с рядом вещей, возможно, или, может быть, не с инкрустацией. Вы можете использовать метод stackshot, упомянутый выше, чтобы точно определить, что происходит в любом случае. Я обнаружил, что отладочные сборки могут быть медленными по другим причинам, например, как рекурсивная проверка структуры данных.

Ответ 2

Разработайте несколько макросов, используя высокопроизводительный механизм синхронизации вашего процессора (например, x86) - подпрограммы, которые не полагаются на системные вызовы и привязать один поток, выполняющий ваш цикл ядра к определенному процессору (установить аффинность). Вам понадобится реализовать следующие макросы.

PROF_INIT //allocate any variables -- probably a const char
PROF_START("name") // start a timer
PROF_STOP() // end a timer and calculate the difference -- 
            // which you write out using a async fd

У меня было что-то подобное, что я поместил в каждую интересующую меня функцию, я убедился, что макрос помещает вызовы синхронизации в контекст дерева вызовов - это, возможно, самый точный способ профилирования.

Примечание:

Этот метод управляется вашим кодом - и не полагается на внешний инструмент, чтобы каким-либо образом отслеживать ваш код. Отслеживание, выборочное и прерывистое профилирование неточно, когда речь идет о небольших разделах кода. Кроме того, вы хотите контролировать, где и когда собираются данные синхронизации - например, в конкретных конструкциях вашего кода, например, циклы, начало рекурсивных распределений цепочек вызовов или массовой памяти.

- изменить -

Вам может быть интересна ссылка из этого ответа на один из моих вопросов.

Ответ 3

Вы можете использовать более мощный профилировщик, такой как Intel VTune, который может дать вам уровень детализации сборки.

http://software.intel.com/en-us/intel-vtune/

Это для Windows и Linux, но стоит денег...

Ответ 4

Может ли valgrind быть более полезным?

В сочетании с KCachegrind GUI предлагает бесплатный и простой способ просмотра аннотированного кода, подходящего для встроенного кода. Здесь у вас довольно простая инструкция: http://web.stanford.edu/class/cs107/guide_callgrind.html

Ответ 5

Не имеет значения, что код работает медленнее (ваше удобство в стороне, конечно) - профилировщик все равно расскажет вам о правильной пропорции времени, затраченного на каждую функцию.

Ответ 6

Вы можете использовать gcov, чтобы дать вам подсчет строк за строкой. Это должно, по крайней мере, сказать вам, какие встроенные функции являются узким местом.