Лучшая практика для секундомера в многопроцессорной машине?

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

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(для предотвращения перекрытия вызовов)

Ответ 1

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

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

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

Ответ 2

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

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

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

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