Подтвердить что ты не робот

Как долго длится одиночное вращение в ManualResetEventSlim

Как долго длится одиночное вращение в С#? Я хочу знать, есть ли ManualResetEventSlim, у которого есть параметр spinCount, и я хочу знать, как долго длится каждый оборот в миллисекундах или как он работает? Я знаю, что вращение более эффективно для коротких ожиданий, чем ожидание ядра. Поэтому я просто пытаюсь понять, для чего я должен установить это значение для задания, которое обычно занимает 2-10 секунд.

4b9b3361

Ответ 1

В конструкторе нет корреляции между параметром spinCount и количеством потраченных миллисекунд, выполняющим ожидание вращения.

Вот как это работает. MRES использует этот параметр spinCount для прохождения своей собственной процедуры ожидания независимо от Thread.SpinWait.

  • Первые 10 итераций чередуются между вызовами Thread.Yield и Thread.SpinWait. Вызов Thread.SpinWait начинается со спина Environment.ProcessorCount * 4 и затем приблизительно удваивается при каждом последующем вызове.
  • После этого каждая итерация делится на 20 вызовов Thread.Sleep(1).
  • В противном случае те, которые делятся на 5, вызывают Thread.Sleep(0).
  • В противном случае вызывается Thread.Yield.
  • CancellationToken проверяется каждые 10 итераций после 100.

Итак, как вы можете видеть, в MRES настраивается обычная рутина. И алгоритм может измениться с версии на версию. Невозможно предсказать, как долго будет длиться каждый прокрутка.

Если ваше типичное время ожидания составляет 2-10 секунд, ваш код почти наверняка будет ждать уровня ядра через координаты Monitor.Wait и Monitor.Pulse, потому что параметр spinCount в любом случае ограничен 2047.

Плюс, 2-10 секунд - это долгое время. Вы действительно хотите так долго прокручивать?

Ответ 2

Количество спинов должно быть небольшим. По умолчанию используется 10 (или 1, если выполняется на одном процессоре). Если вы используете конструктор, который позволяет указать количество оборотов, максимально допустимое значение равно 2047. Если событие не сигнализируется очень быстро, ManualResetEventSlim использует регулярное ожидание обработки события. Как отметил @HenkHolterman, время, занятое, намного, намного больше, чем секунды. Мы говорим о циклах, а не секундах или даже миллисекундах.

http://msdn.microsoft.com/en-us/library/5hbefs30.aspx

В .NET Framework версии 4 вы можете использовать Класс System.Threading.ManualResetEventSlim для лучшей производительности когда ожидаемое время ожидания будет очень коротким, а когда событие не пересекать границу процесса. ManualResetEventSlim использует занятое прядение в течение короткого времени, пока он ждет, когда событие станет сигналом. когда время ожидания короткое, вращение может быть намного дешевле, чем ждать используя дескрипторы wait. Однако, если событие не становится сигналом в течение определенного периода времени, ManualResetEventSlim прибегает к регулярное управление событиями.

http://msdn.microsoft.com/en-us/library/ee722114.aspx

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

РЕДАКТИРОВАТЬ: Чтобы ответить на ваш вопрос напрямую, хотя на время полного вращения нельзя ответить окончательно, поскольку он зависит от оборудования, на котором он работает. http://msdn.microsoft.com/en-us/library/system.threading.thread.spinwait(v=vs.95).aspx

SpinWait существенно переводит процессор в очень плотный цикл, с число циклов, заданное параметром итераций. Продолжительность поэтому ожидание зависит от скорости процессора.