2009-07-07 18 views

Respuesta

98

no. Se usa como reemplazo de llamadas de sueño a muy corto plazo.

Cuando realiza el bloqueo de subprocesos múltiples, si el recurso que está intentando adquirir ya está bloqueado, normalmente se queda dormido y espera a que se libere. Cuando hace esto, abandona el resto del tiempo que el planificador le asignó para usar el procesador para que alguien más pueda probarlo. Normalmente, esto está bien, especialmente para esperas prolongadas, como esperar por IO, cargas de otros procesos pueden ejecutarse en la CPU mientras espera que el eje del disco gire.

Sin embargo, a veces, está esperando una pequeña cantidad de tiempo. En estos casos, normalmente perderías el tiempo restante de todos modos y esperarás a que todos los otros hilos hagan lo suyo antes de intentarlo otra vez ... para que puedas hacer trampa, en lugar de esperar, te sientas ahí continuamente en una '¿estamos cerca? ¿Todavía ahí?' camino. Si el bloqueo solo se mantiene durante una fracción del tiempo restante, se convierte en un medio muy eficaz de esperar, también es muy eficiente ya que el programador no tiene que involucrarse en reorganizar todos los otros hilos para usar el tiempo que abandona si esperaste normalmente

Obviamente, si gira cada vez que quiere un bloqueo, no va a ser muy popular, su aplicación se volverá lenta y usará 100% de CPU, pero en dosis muy pequeñas, en el momento correcto, hace la aplicación más receptiva.

Si ahora está pensando "¿cuándo debería usarlo?", Es una llamada difícil de hacer: si tiene un recurso que muy a menudo se bloquea y desbloquea muy rápidamente, entonces un spinlock alrededor de eso en lugar de esperar es una buena idea (y luego prueba tu rendimiento de la aplicación), si tratas de girar por un corto tiempo y luego vuelves a una espera normal, también es una manera razonable. Pero en general, nunca necesitarás usarlo.

+0

Digamos que queremos lograr un retraso de 50 ms en promedio, ¿cuántas iteraciones tenemos? especifique? –

+3

'SpinWait' rara vez hará que se quede atascado al 100% de utilización de la CPU. Esto se debe a que comienza a hacer que el hilo ceda o duerma si gira demasiado tiempo. Específicamente, si el número de vueltas es mayor o igual a 10, 'dormirá (1)' por cada 19º giro y 'duerme (0)' por cada 4º giro, y 'cederá 'si y solo si se determina que el próximo giro tiene potencial de rendimiento. Puede' dormir ' o 'rendimiento 'en sistemas multiprocesador en cualquier punto y no necesita esperar los 10 giros iniciales. En un solo sistema de procesador, solo 'dormirá' o' cederá' si el conteo de centrifugado es 10 o menos. –

+3

@ MichaelJ.Gray: Estás confundiendo 'Thread.SpinWait()' (la pregunta y la respuesta) con 'var sw = new SpinWait(); sw.SpinOnce(); 'que hace la cuenta de vueltas interna hasta 10 ... – DeepSpace101

70

El propósito es hacer una espera "barata" si usted cree que la condición que está esperando se hará realidad muy, muy pronto. Normalmente, si estás esperando algo, dejas que el hilo se quede dormido y el procesador/sistema operativo cambiará de contexto a otro hilo. Los interruptores de contexto no son particularmente baratos, por lo que si tiene un conocimiento avanzado de la situación y cree que es más económico esperar que cambiar de contexto, aguarde la espera.

Mi consejo: si necesita preguntar, no necesita usarlo. (Nunca lo he querido). Básicamente es una de esas cosas que es realmente útil en muy pocas situaciones, pero la mayoría de la gente debería irse sola.

+3

Creo que este va con toda la categoría de "a menos que haya medido y haya encontrado un problema ..." – jerryjvl

5

Por lo que a mí respecta (y estoy feliz por las correcciones), el único uso de espín espera es cuando se implementa un mecanismo de bloqueo o devolución de llamada entre hilos. Y ninguno debe hacerse manualmente (generalmente), ya que existen.

Cuando ha bloqueado un recurso y otro hilo solicita acceso sincronizado a él, básicamente tiene que esperar a que el primer hilo termine de usarlo. Esta espera se puede hacer simplemente girando en un bucle (o de lo contrario durmiendo + cambio de contexto como lo menciona Jon).

+2

Una excepción: dentro del ciclo' Render() 'de un motor de juegos para limitar la velocidad de cuadros. Ninguno de los otros mecanismos' Sleep() 'proporciona una garantía suficiente sobre cuándo volverá a conectarse. – Basic

+2

@Basic Es cierto, aunque lo que a menudo se hace es saltear vueltas en el ciclo de renderizado en lugar de tener un ciclo de espera explícito (anidado). El efecto es el mismo por supuesto. –

14

Como nota al margen, Microsoft se ha deshecho del mecanismo de spinlock del despachador de subprocesos de Windows 7, ya que no se ha escalado bien para las CPU multinúcleo. Eche un vistazo a this:

+1

Dice que se han deshecho de un spinlock que usan en Windows: el spinlock del despachador. – Kevin

Cuestiones relacionadas