2016-04-20 2 views
1

Я работаю над проектом с интенсивным вычислением C#, который реализует несколько алгоритмов. Проблема в том, что когда я хочу профилировать мое приложение, время, которое требуется для определенного алгоритма, меняется. Например, иногда выполнение алгоритма 100 раз занимает около 1100 мс, а другое время 100 раз занимает гораздо больше времени, например, 2000 или даже 3000 мс. Он может меняться даже в том же режиме. Таким образом, невозможно измерить улучшение, когда я оптимизирую фрагмент кода. Это просто ненадежно.Установить аффинность процессора для профилирования

enter image description here

Вот другой ход:

enter image description here

Поэтому в основном я хочу, чтобы убедиться, что один процессор предназначен для моего приложения. ПК имеет старый двухъядерный процессор Intel E5300, работающий на Windows 7 32 бит. Поэтому я не могу просто определить близость процесса и забыть о одном ядре навсегда. Это сделало бы компьютер очень медленным для ежедневных задач. Мне нужно, чтобы другие приложения использовали конкретное ядро, когда захочу, и когда я закончил профилирование, сродство к процессору вернется к норме. Наличие файла bat для выполнения этой задачи было бы фантастическим решением.

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

PS: Алгоритм правилен и каждый раз выполняется один и тот же путь кода. Я создал некоторый пул объектов, поэтому после первого запуска выделяется нулевая память. Я также профилировал выделение памяти с помощью dottrace, и после первого запуска он не показывал выделения. Поэтому я не считаю, что GC запускается, когда алгоритм работает. Доступна физическая память, и в ОЗУ система не работает.

Результат: Ответ Криса Бекка выполняет задание и устанавливает сходство процессов точно так же, как и предполагалось. Это привело к получению более единообразных результатов, особенно когда запускаются фоновые приложения, такие как visual studio и dottrace. Дальнейшее исследование расходящегося времени выполнения показало, что корень для непредсказуемости - перегрев процессора. Сигнал перегрева процессора отключился, когда температура была выше 100 ° C! Поэтому после фиксации неисправного вентилятора результаты стали полностью однородными.

+0

Никогда не обращайте внимание на бенчмарк, который просто дает оптимистично хорошие результаты, которые никогда не воспроизводятся на производстве. Если вы используете * double * в своем расчетном коде, и вы запускаете его в 32-битном режиме, вы можете получить 3 отдельных тайминга. Худший случай - это жир x3 медленнее, чем в лучшем случае. Пахнет, вот что происходит. Удалите дрожание, чтобы он мог работать в 64-битном режиме. Проект> Свойства> вкладка «Сборка»> «Платформа цели» = «AnyCpu» и «Предпочитаете 32-битную». –

+0

@HansPassant Я проверил настройки проекта, и он находится на любом процессоре, а опция 32bit не установлена.Я понимаю вашу мысль о том, чтобы не докториться эталоном. Проблема, с которой я сталкиваюсь, заключается в том, что одно и то же время выполнения кода сильно варьируется даже в том же запущенном сеансе. На скриншотах показано, что иногда время выполнения различно для каждого вызова, а иногда и то же самое. Я не пытаюсь добиться искусственного выигрыша. Я хочу надежную и повторяемую среду, поэтому каждый раз, когда я пытаюсь оптимизировать метод, я знаю, если он делает код быстрее или медленнее. –

+0

Ну, похоже, у вас 32-разрядная ОС, поэтому эти настройки не будут иметь никакого значения. Если вы не можете получить 64-битную ОС, тогда просто двигайтесь дальше, она не будет красивее. Возьмите медианную и назовите ее днем. –

ответ

2

Вы имеете в виду SetProcessAffinityMask?

Я вижу этот вопрос, в то время как отмеченные окна, является C#, поэтому ... Я вижу, что объект System.Diagnostics.Process имеет член ThreadAffinity, который должен выполнять ту же функцию.

Я просто не уверен, что это стабилизирует время процессора так, как вы ожидаете. Одна занятая задача, которая не выполняет IO, должна оставаться запланированной на одном и том же ядре, если другой поток не прерывает ее, поэтому я думаю, что ваше время переменной больше связано с другими потоками/процессами, прерывающими ваш алгоритм, чем операционная система, случайным образом шунтирующая вашу нить к другому core - поэтому, если вы не установите привязанность ко всем другим потокам в системе, чтобы исключить ваше предпочтительное ядро, я не вижу этой помощи.

+0

На самом деле я прошу указать способ привязки всего другого процесса, чтобы они не влияли на производительность моего приложения. Я удалил тэг C#, потому что он несколько вводил в заблуждение. Извини за это. –

+1

Итак, SetProcessAffinityMask будет делать то, что вы хотите. 'EnumProcesses' будет заполнять массив идентификаторами процесса, а' OpenProcess' преобразует их в РУЧКИ, необходимые для 'SetProcessAffinityMask'. Вероятно, у вас возникнут некоторые проблемы с разрешениями, открывающие определенные системные процессы. Не забудьте снова положить все это. –

+0

Учитывая, что это не производственный код, вы можете получить лучшие результаты, просто увеличив приоритет потока через 'SetThreadPriority' –