Наилучшая практика для секундомера в многопроцессорной машине? - PullRequest
8 голосов
/ 19 июля 2009

Я нашел хороший вопрос для измерения производительности функции, и в ответах рекомендуется использовать секундомер следующим образом

Stopwatch sw = new Stopwatch();
sw.Start();
//DoWork
sw.Stop();
//take sw.Elapsed

Но верно ли это, если вы работаете на машине с несколькими процессорами? поток может быть переключен на другой процессор, не так ли? Также то же самое должно быть в Enviroment.TickCount. Если ответ «да», должен ли я обернуть свой код внутри BeginThreadAffinity следующим образом

Thread.BeginThreadAffinity();
Stopwatch sw = new Stopwatch();
sw.Start();
//DoWork
sw.Stop();
//take sw.Elapsed
Thread.EndThreadAffinity();

P.S

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

Я использую секундомер не только для измерения производительности, но и для имитации функции таймера с использованием Thread.Sleep (для предотвращения наложения вызовов)

Ответы [ 2 ]

5 голосов
/ 19 июля 2009

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

Если ваша машина занята другими делами, это может сделать ваш тест недействительным (например, кодирование видео H.264 при выполнении теста с привязкой к ЦП). Аналогично, если вы используете всю физическую память при тестировании чего-либо, связанного с памятью, это может сделать ваши результаты недействительными.

Таким образом, общий принцип заключается в том, что машина должна находиться под минимальной или нормальной нагрузкой при проведении таких испытаний. Кроме этого нет проблемы многопроцессорности. Да, программа может поменять местами ядра во время работы, но накладные расходы, связанные с этим, составляют либо небольшой процент от вашего измеренного времени, либо измеренное время настолько мало, что гранулярность измерения времени системы является проблемой.

2 голосов
/ 22 ноября 2011

Я думаю, что вы спрашиваете о низкоуровневой реализации секундомера и о том, может ли переключение процессоров в середине выполнения сделать недействительным поведение. Реализация действительно использует QueryPerformanceCounter для внутреннего использования (см. Справочные источники MS BCL; я подтвердил его, по крайней мере, в .NET 4.0.)

Документация MS для этого API гласит:

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

Итак, вы правы; в принципе, это не должно иметь значения, но этот комментарий предполагает, что были случаи, когда реализация не соответствовала предполагаемому интерфейсу. Если вы хотите гарантировать правильность измерения, вы можете использовать привязку нитей, как вы заявили. Тем не менее, я предполагаю, что любые обнаруженные ошибки довольно малы, поскольку большая разница будет довольно серьезной ошибкой BIOS или HAL.

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