Pregunta

He visto a una pregunta acerca de por qué "de votación es malo". En términos de minimizar la cantidad de tiempo de procesador utilizado por un hilo, sería mejor que hacer una espera de giro (es decir sondeo para un cambio requerido en un bucle while) o esperar en un objeto de núcleo (por ejemplo, un objeto de evento de núcleo en Windows) ?

Para el contexto, se supone que se requiere el código para funcionar en cualquier tipo de procesador, de un solo núcleo, hyperthreaded, multinúcleo, etc. También suponga que un hilo que sondear o esperar no puede continuar hasta que el resultado de votación es satisfactoria si se sondea en lugar de espera. Finalmente, el tiempo entre cuando un subproceso comienza en espera (o polling) y cuando se cumple la condición puede variar potencialmente desde un tiempo muy corto para un largo tiempo.

Dado que el sistema operativo es probable que de manera más eficiente "encuesta" en el caso de "espera", no quiero ver el "esperando simplemente significa que alguien más lo hace el sondeo" argumento, eso es noticia vieja, y no es necesariamente 100% exacto.

¿Fue útil?

Solución

Siempre que el sistema operativo tiene implementaciones razonables de estos tipos de primitivas de concurrencia, es definitivamente mejor que esperar en un objeto de núcleo.

Entre otras razones, esto permite que el sistema operativo no sabe programar el hilo en cuestión de fracciones de tiempo adicional hasta que el objeto que se esperaba para-está en el estado apropiado. De lo contrario, usted tiene un hilo que constantemente está siendo reprogramado, contexto ha cambiado-a-y, a continuación, ejecutar a la vez.

Usted preguntó específicamente acerca de reducir al mínimo el tiempo de procesador de un hilo: en este ejemplo el hilo de bloqueo en un objeto de núcleo utilizaría tiempo cero; el hilo de votación sería utilizar todas las clases de tiempo.

Además, la "otra persona está sondeando" argumento no tiene por qué ser cierto. Cuando un objeto de núcleo entra en el estado apropiado, el núcleo puede mirar a ver en ese instante, que las discusiones están a la espera de ese objeto ... y luego programar uno o más de ellos para su ejecución. No hay necesidad de que el núcleo (o cualquier otra persona) para sondear nada en este caso.

Otros consejos

La espera es el camino "mejor" a comportarse. Cuando se está esperando en un kernel objetar el hilo no se concederá ningún tiempo de CPU como se le conoce por el planificador que no hay trabajo listo. Su único hilo se va a dar tiempo de CPU cuando es esperar condición se cumple. Lo que significa que no será acaparando los recursos de CPU innecesariamente.

Creo que un punto que no se ha planteado todavía es que si su sistema operativo tiene mucho trabajo por hacer, bloqueando yeilds el hilo a otro proceso. Si todos los procesos usan las primitivas de bloqueo donde deben (como núcleo espera, archivo / IO de red, etc.) que está dando el núcleo más información para elegir qué temas deben ejecutar. Como tal, se va a hacer más trabajo en la misma cantidad de tiempo. Si su aplicación podría estar haciendo algo útil a la espera de que el archivo que desea abrir o el paquete para llegar a continuación, se yeilding incluso ayudar eres propia aplicación.

Espera involucra más recursos y un medio de cambio de contexto adicional. De hecho, algunas primitivas de sincronización como monitores CLR y Win32 secciones críticas utilizan un protocolo de bloqueo de dos fases - algunos esperando giro se realiza proa haciendo realmente un verdadero espera

.

Me imagino haciendo lo de dos fases sería muy difícil, e implicaría una gran cantidad de pruebas y la investigación. Por lo tanto, a menos que tenga el tiempo y los recursos, se adhieren a las primitivas ventanas ... ya lo hicieron la investigación para usted.

Hay sólo unos pocos lugares, por lo general dentro de las cosas de bajo nivel del sistema operativo (interrumpir conductores controladores / dispositivos), donde escisión de espera tiene sentido / se requiere. aplicaciones de uso general son siempre mejor esperar en algunas primitivas de sincronización como exclusiones mutuas / variables condicionales / semáforos.

Estoy de acuerdo con Darksquid, si su sistema operativo tiene primitivas de concurrencia decente, entonces no debería tener que sondear. de votación por lo general viene en su propio en sistemas de tiempo real o hardware restringida que no tiene un sistema operativo, entonces usted necesita para sondear, porque puede que no tenga la opción de esperar (), sino también porque le da el control de grano fino sobre exactamente cuánto tiempo quiere esperar en un estado particular, en lugar de estar a merced del planificador.

Espera (bloqueo) es casi siempre la mejor opción ( "mejor" en el sentido de hacer un uso eficiente de los recursos de procesamiento y minimizar el impacto a otro código que se ejecuta en el mismo sistema). Las principales excepciones son:

  1. Cuando la duración esperada de votación es pequeño (similar en magnitud al coste de la llamada al sistema de bloqueo).
  2. Sobre todo en sistemas embebidos, cuando la CPU está dedicado a la realización de una tarea específica y no haya un beneficio de tener la inactividad de la CPU (por ejemplo, algunos enrutadores de software construidos en los últimos años 90 se utilizan este enfoque.)

El sondeo generalmente no se usa dentro de los núcleos del sistema operativo para implementar el sistema de bloqueo de llamadas -. En su lugar, los eventos (interrupciones, temporizadores, acciones sobre los mutex) dar lugar a un proceso bloqueado o el hilo que se hizo ejecutable

Existen cuatro enfoques básicos que se podría tomar:

  1. Use un poco de espera OS primitiva que esperar hasta que se produzca el evento
  2. Use un poco de temporizador OS primitiva para comprobar en algún tipo definido si el suceso ha ocurrido todavía
  3. repetidamente comprobar si se ha producido el evento, pero el uso de un sistema operativo primitiva para producir un segmento de tiempo con una duración arbitraria y desconocido en cualquier momento que no tiene.
  4. repetidamente comprobar si se ha producido el evento, sin ceder a la CPU si no lo ha hecho.

Cuando # 1 es práctica, a menudo es el mejor enfoque a menos retrasar la respuesta de uno al evento podría ser beneficioso. Por ejemplo, si uno está esperando a recibir una gran cantidad de datos de puerto serie a lo largo de varios segundos, y si el procesamiento de 100 ms de datos después de que se envíe será tan bueno como el procesamiento al instante, el sondeo periódico usando uno de los dos últimos enfoques podría ser mejor que la creación de un evento de "datos recibidos".

Enfoque # 3 es bastante crudo, pero puede ser en muchos casos una buena. A menudo se pierda más tiempo de CPU y recursos que se acercaría a # 1, pero en muchos casos ser más fácil de implementar y el desperdicio de recursos en muchos casos ser lo suficientemente pequeño como para no tener importancia.

Enfoque # 2 es a menudo más complicado que # 3, pero tiene la ventaja de ser capaz de manejar muchos recursos con un único contador de tiempo y sin un hilo dedicado.

Enfoque # 4 veces es necesario en sistemas embebidos, pero en general es muy malo que el que no directamente al hardware de votación y la voluntad de no tener nada útil que hacer hasta que se produce el evento en cuestión. En muchas circunstancias, no será posible para la afección que se esperó a que se produzca hasta que el hilo espera de que se obtiene la CPU. Ceder la CPU como en el enfoque # 3, de hecho, permitir que el hilo de espera para ver el evento antes de lo que se acaparando.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top