2012-04-24 14 views
12

¿Cuánto dura un giro único en C#? Lo que quiero saber es que hay un ManualResetEventSlim que tiene un parámetro spinCount y quiero saber cuánto dura cada giro en milisegundos o cómo funciona. Sé que girar es más eficiente para las esperas cortas que esperar un kernel. Así que solo estoy tratando de ver para qué debo establecer este valor para un trabajo que generalmente dura de 2 a 10 segundos.¿Cuánto dura un giro único en ManualResetEventSlim

+0

2-10 .. qué? ¿Te refieres a microsegundos? –

+4

Spinning es en nanosegundos y simplemente no lo hace durante 2-10 segundos ... ni siquiera durante 2-10 milisegundos. –

Respuesta

24

No hay correlación entre spinCount parámetro en el constructor y el número de milisegundos empleados haciendo un giro de espera.

Así es como funciona. MRES utiliza este parámetro spinCount para pasar por su propia rutina de espera independiente de Thread.SpinWait.

  • La primera 10 iteraciones alternativo entre llamar Thread.Yield y Thread.SpinWait.La llamada al Thread.SpinWait comienza con un giro de Environment.ProcessorCount * 4 y luego se duplica aproximadamente en cada llamada sucesiva.
  • A continuación, cada iteración divisible por 20 llama a Thread.Sleep(1).
  • De lo contrario, los divisibles por 5 llaman a Thread.Sleep(0).
  • De lo contrario, se llama Thread.Yield.
  • El CancellationToken se comprueba cada 10 iteraciones después de 100.

Así como se puede ver que hay una bastante complejo de canto y de baile pasando dentro de la rutina de giro de encargo de MRES. Y el algoritmo podría cambiar de una versión a otra. Realmente no hay forma de predecir cuánto durará cada giro.

Si los tiempos de espera son típicos 2-10 segundos y luego su código es casi seguro que va a hacer una espera de nivel de núcleo a través de Monitor.Wait y Monitor.Pulse coordinaciones porque el parámetro spinCount se limita a 2047 de todos modos.

Más, 2-10 segundos es un largo tiempo. ¿Realmente quieres girar tanto?

+0

+1 para obtener detalles interesantes. ¡Intenta realmente conseguir el otro hilo para liberar el bloqueo! –

+0

Publicación de distancia, siempre que no esperes que la conteste Me gustaría saber también. En las raras ocasiones en que he usado sleep (0)/sleep (1), (depuración solamente), no he visto ninguna diferencia en el rendimiento. –

+0

"approximately"? – Gabe

12

El número de vueltas debe ser pequeño. El valor predeterminado es 10 (o 1 si se ejecuta en un solo procesador). Si utiliza el constructor que le permite especificar el recuento de centrifugado, el máximo permitido es 2047. Si el evento no se señaliza muy rápidamente, ManualResetEventSlim utiliza una espera de identificador de evento regular. Como mencionó @HenkHolterman, los tiempos involucrados son mucho, mucho más pequeños que segundos. Estamos hablando de ciclos, no segundos o incluso milisegundos.

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

En la versión de .NET Framework 4, se puede utilizar la clase System.Threading.ManualResetEventSlim para un mejor rendimiento cuando se espera que los tiempos de espera a ser muy corto, y cuando el caso lo hace no cruzar un límite de proceso. ManualResetEventSlim utiliza el spinning ocupado durante un tiempo breve mientras espera a que se marque el evento. Cuando los tiempos de espera son cortos, girar puede ser mucho menos costoso que esperar usando los controles de espera. Sin embargo, si el evento no recibe la señal de dentro de un cierto período de tiempo, ManualResetEventSlim recurre a un espera de identificador de evento regular.

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

En los equipos multinúcleo, cuando no se espera un recurso que tendrá lugar durante largos períodos de tiempo, puede ser más eficiente para una hilo esperando para girar en modo de usuario para una pocas docenas o cientos de ciclos, y luego vuelva a intentar para adquirir el recurso. Si el recurso está disponible después de girar, entonces ha guardado varios miles de ciclos. Si el recurso aún no está disponible, solo ha gastado unos pocos ciclos y aún puede ingresar una espera basada en kernel.

EDITAR: Para responder a su pregunta directamente, no se puede responder definitivamente al tiempo de un solo giro, ya que depende del hardware en el que se está ejecutando. http://msdn.microsoft.com/en-us/library/system.threading.thread.spinwait(v=vs.95).aspx

SpinWait pone esencialmente el procesador en un bucle muy apretado, con el recuento de bucle especificado por el parámetro iteraciones. La duración de espera, por lo tanto, depende de la velocidad del procesador.

Cuestiones relacionadas