Как рассчитать загрузку процессора для части кода .NET? - PullRequest
6 голосов
/ 18 января 2011

Наш инструмент генерирует журналы производительности в режиме диагностики, однако мы отслеживаем производительность, как во время выполнения кода ( Секундомер + милисекунды ).

Очевидно, что это вообще ненадежно, ЦП тестирующей системы может быть использован каким-то случайным процессом, результаты будут совершенно разными, если вы настроили инструмент для запуска 10 потоков вместо 2 и т. Д.

Мой вопрос:

Как правильно определить правильное время ЦП для фрагмента кода ( не для всего процесса )?

Что я имею в виду под временем ЦП:

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

PS Использование профилировщика невозможно в нашей настройке

Еще одно обновление,

Почему я не собираюсь использовать профилировщик

Потому что нам нужно тестировать код в разных средах с разнымиданные, где у нас нет профилировщика или IDE или что-то в этом роде.Следовательно, сам код должен справиться с этим.Крайним вариантом может быть использование DLL профилировщика, но я не думаю, что эта задача требует такого сложного решения ( при условии, что не существует бесплатной и простой для реализации библиотеки профилирования ).

Ответы [ 3 ]

4 голосов
/ 18 января 2011

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

Это просто не то, как работают компьютеры. На код очень влияет другие процессы, выполняющиеся на машине. Типичный компьютер с Windows имеет около 1000 активных потоков, число которых вы можете увидеть на вкладке «Производительность» Taskmgr.exe. Подавляющее большинство из них спят, ожидая какого-то события, сигнализируемого Windows. Тем не менее, если на машине запущен код, включая ваш, который готов к работе и занимает процессорное время, тогда Windows предоставит всем им кусок пирога.

Что делает измерение количества времени, затраченного вашим кодом, довольно произвольным измерением. Единственное, что вы можете оценить, это минимальное количество времени, затрачиваемое. То, что вы делаете, выполняя тест десятки раз, вполне вероятно, что вы получите образец, на который не влияли другие процессы. Это, однако, никогда не случится в реальной жизни, поэтому было бы разумно принять значение медиана в качестве реалистичного измерения производительности.

Единственное действительно полезное измерение - это измерение дополнительных улучшений вашего алгоритма. Измените код, посмотрите, как из-за этого меняется среднее время.

1 голос
/ 13 февраля 2011

Лучший способ измерить процессорное время - использовать инструкцию "rdtsc" или "Считать счетчик меток времени".Этот счетчик (часть самого ЦП) увеличивается на внутреннюю тактовую частоту ЦП.Таким образом, разница между двумя показаниями - это количество прошедших тактов.Этот счетчик может быть интегрирован в ваш код, если он (код) не слишком высокого уровня (хотя и не совсем уверен).Вы можете измерять время на диске, время в сети, время в CPU и т. Д. - возможности безграничны.Если вы поделите количество прошедших тактов на частоту вашего процессора в мегагерцах, вы получите, например, истекшее количество микросекунд.Это довольно хорошая точность, и лучше это сделать. Создайте графический интерфейс, который взаимодействует с вашей статистикой использования ЦП.

Найдите «rdtsc» или « rdtsc» или « _rdtsc» в файлах справки дляваше окружение.

1 голос
/ 18 января 2011

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

Процессорное время, используемое функцией, является очень гибким понятием.

  • Включает ли он ввод-вывод, выполняемый где-либо под ним в дереве вызовов?
  • Это только «время сам» или включительно для вызываемых абонентов?(В серьезном коде собственное время обычно равно нулю.)
  • Усредняется ли оно по всем вызовам?Определите «все».
  • Кто использует эту информацию, для каких целей?Чтобы найти так называемые "узкие места"?Или просто какая-то цель отслеживания регрессии?

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

  • Он сообщает процент времени включения.
  • Он дает процент на уровне строки (а не только на уровне функции), поэтому он определяет дорогостоящие строки кода, будь то илине они являются вызовами функций.
  • Он включает в себя ввод-вывод, а также процессорное время.(В серьезном программном обеспечении нецелесообразно исключать время ввода-вывода, потому что вы действительно не знаете, что тратит время несколькими слоями ниже в дереве вызовов.)
  • Это относительно нечувствительно к конкуренции за ЦПдругие процессы или скорость процессора.
  • Для поиска дорогостоящего кода не требуется высокая частота дискретизации или большое количество выборок.( Это распространенное заблуждение. ) Каждая дополнительная цифра точности измерения требует примерно в 100 раз больше выборок, но это не позволяет найти более дорогой код более точно.

Профилировщикпо этому принципу работает Zoom .

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

...