Какие методы вы можете использовать для профилирования вашего кода - PullRequest
3 голосов
/ 13 ноября 2008

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

Целевой язык - C ++.

Мне интересно, что вы лично использовали.

Ответы [ 7 ]

8 голосов
/ 13 ноября 2008

Без шуток. В дополнение к выводу времени в std :: cout и другим подходам, ориентированным на текст / данные, я также использую функцию Beep (). Есть что-то в слуховой щели между двумя контрольными точками "Beep", что производит разное впечатление.

Это похоже на разницу между просмотром нот и написанием музыки. Это как разница между чтением rgb (255,0,0) и красным огнем.

Итак, прямо сейчас у меня есть приложение клиент / сервер и с звуковыми сигналами различной частоты, отмечающими, где клиент отправляет сообщение, где сервер начинает свой ответ, заканчивает свой ответ, где ответ сначала входит в клиент и т. Д., Я очень естественно чувствую, где время проведено.

5 голосов
/ 13 ноября 2008

Я нашел следующее весьма полезным:

#ifdef PROFILING
# define PROFILE_CALL(x) do{ \
    const DWORD t1 = timeGetTime(); \
    x; \
    const DWORD t2 = timeGetTime(); \
    std::cout << "Call to '" << #x << "' took " << (t2 - t1) << " ms.\n"; \
  }while(false)
#else
# define PROFILE_CALL(x) x
#endif

Который можно использовать в вызывающей функции как таковой:

PROFILE_CALL(renderSlow(world));
int r = 0;
PROFILE_CALL(r = readPacketSize());
3 голосов
/ 13 ноября 2008

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

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

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

2 голосов
/ 13 ноября 2008

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

2 голосов
/ 13 ноября 2008

Если это что-то достаточно длинное (например, минута или более), я запускаю программное обеспечение в отладчике, затем несколько раз прерываю работу и вижу, где происходит сбой отладчика, это дает очень приблизительное представление о том, что работает программное обеспечение. к (например, если вы сломаете 10 раз, и они все в одном месте, это говорит вам кое-что интересное!). Очень грубый и готовый, но не требует никаких инструментов, инструментов и т. Д.

1 голос
/ 14 ноября 2008

Вы используете Visual Studio?

Вы можете использовать переключатели / Gh и / GH. Вот пример, включающий проверку стека

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

Затем вы можете зарегистрировать все данные профилирования, а не только информацию о времени. Стеки-дампы, адрес вызова, адрес возврата и т. Д. Что важно, потому что вы можете знать, что «функция X использовала время Y под функцией Z», а не только общее время, проведенное в функции X.

1 голос
/ 13 ноября 2008

Я бы использовал правило 80/20 и поместил бы таймеры вокруг горячих точек или интересных путей вызова. Вы должны иметь общее представление о том, где будут узкие места (или, по крайней мере, большинство путей выполнения), и использовать соответствующий зависящий от платформы таймер высокого разрешения (QueryPerformanceCounters, gettimeofday и т. Д.).

Я обычно ничего не беспокою при запуске или завершении работы (если не требуется), и у меня будут четко определенные «точки дросселирования», обычно передача сообщений или какой-то алгоритм алгоритмического расчета. Как правило, я обнаружил, что приемники сообщений / srcs (приемники более), очереди, мьютексы и просто простые сообщения (алгоритмы, циклы) обычно составляют большую часть задержки в пути выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...