2016-03-13 2 views
7

Я недавно использовал некоторые базовые тесты, написанные на C#, чтобы попытаться определить причину, по которой некоторые, казалось бы, идентичные удаленные рабочие станции HyperV работают намного медленнее, чем другие. Их результаты по большинству основных тестов, которые я запускаю, были полностью идентичны, но результаты базового теста доступа к базовой памяти (в частности, время, затрачиваемое на инициализацию двумерного массива удвоений 1000x1000 до 0), различаются в 40 раз.Почему мои тесты памяти дают странные результаты?

Для дальнейшего изучения этого вопроса я провел несколько других экспериментов, чтобы еще больше сузить вопрос. Выполнение одного и того же теста с экспоненциально увеличивающимся размером массива (пока не произойдет OutOfMemoryException) не показывает разницы между различными пультами до тех пор, пока размер массива не превысит 1 м, а затем немедленную разницу в 40. Фактически, время, затрачиваемое на инициализацию, увеличивается пропорционально размеру массива до размера массива точно 999999, а затем на «медленных» пультах время увеличивается на 900%, тогда как на «быстрых» пультах уменьшается на 70% по мере достижения размера массива 1000x1000. Оттуда он продолжает масштабироваться пропорционально. То же самое происходит и с размерами массива 1 м х 1 и 1 х 1 м, но в гораздо меньшей степени (изменения + 50% и -30%.

Интересно, что изменение типа данных, используемого для эксперимента, Поплавки, по-видимому, полностью устраняют это явление. Между пультами в любом тесте не происходит никакой разницы, и время, проведенное, кажется, полностью пропорционально даже по точкам останова 1000 * 1000 и 2000 * 2000. Еще одним интересным фактором является то, что локальная рабочая станция, Использование поведения пользователя, похоже, отражает поведение более медленных пультов.

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

+3

Все ли рабочие станции имеют ту же конфигурацию оборудования? Обычно правильный ход действий заключается в устранении всех переменных в уравнении. Я обычно делаю это до плохой конфигурации оборудования или просто плохого оборудования. Кстати, это более чем вероятно будет закрыто как _Too Broad_ - я рекомендую конкретно спросить, что можно сделать для отладки и решения этой проблемы. – Qix

+0

Что сказал @Qix. Первое, что я хотел бы проверить, заключается в том, настроены ли виртуальные машины Hyper-V с включенной функцией динамической памяти. –

+0

Можете ли вы предоставить контрольный код? Я часто считаю, что контрольные показатели являются ошибочными. Также проверьте версию исполнения (используйте «детектор версии .NET»). – usr

ответ

9

Вам нужно иметь в виду, что вы есть действительно тестирование. Скорее всего, это не способность .NET-программы назначать элементы массива. Это очень быстро и обычно продолжается, это полосы памяти для большого массива, обычно ~ 37 гигабайт в секунду, в зависимости от типа оперативной памяти, которую имеет машина, 5 ГБ/сек на самый писк, с которым вы могли столкнуться сегодня (медленная синхронизация DDR2 на старая машина).

Ключевое слово new выделяет только адресное пространство на операционную систему с виртуальной памятью под заказ, например Windows. Просто номера процессора, по одному на каждые 4096 байт.

После того, как вы начинаете присваивать элементы при первом запуске, функция вызова по требованию запускается, а ваш код заставляет операционную систему выделять ОЗУ для массива. Назначение элемента массива вызывает ошибку страницы, по одному на каждые 4096 байт в массиве. Или 512 удваивается для вашего массива. Стоимость обработки ошибки страницы включена в ваше измерение.

Это плавное плавание только тогда, когда ОС имеет нулевую инициализированную страницу ОЗУ, готовую к использованию. Обычно принимает жир половину микросекунды, дайте или возьмите. Еще много времени на процессор, он будет остановлен, когда ОС обновит отображение страниц. Имейте в виду, что это происходит только при первом доступе к элементу, а последующие - быстрее, так как страница RAM остается доступной. Как правило.

Это не плавный парус, когда такая страница RAM недоступна. Тогда ОС должна разграбить одну. В вашем случае существует всего 4 различных сценария, которые я могу придумать:

  • страница доступна, но еще не инициализирована нулевой нитью страницы нисходящей нити.Быть быстрым, это не требует больших усилий.
  • страницу должна быть украдена из другого процесса, и содержимое этой страницы не нужно сохранять. Случается для страниц, которые ранее содержали код, например. Довольно быстро.
  • страница должна быть украдена и ее содержимое необходимо сохранить в файле подкачки. Случается для страниц, которые ранее содержали данные, например. Жесткая ошибка страницы, которая болит. Процессор будет остановлен при записи диска.
  • , специфичный для вашего сценария, диспетчер HyperV решает, что ему нужно занять больше оперативной памяти от операционной системы хоста. Все предыдущие пули применимы к этой ОС, а также накладные расходы на взаимодействие с ОС. Нет реальной идеи, сколько накладных расходов влечет за собой, также должно быть болезненно.

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

Долгий и короткий, что профилирование этого кода просто не имеет смысла. Все может и произойдет, и у вас нет достойного способа предсказать это. Или хороший способ сделать что-нибудь об этом, кроме предоставления VM-буфетов ОЗУ и не запускать что-либо еще на нем :) Результаты профилирования для второго, проходящего через массив, будут намного более стабильными и значимыми, ОС теперь больше не задействована.

Смежные вопросы