Subprocesos computacionales programados por una biblioteca de tiempo de ejecución
En programación informática , un hilo virtual es un hilo administrado por una biblioteca de tiempo de ejecución o una máquina virtual (VM) y diseñado para parecerse a un hilo del sistema operativo "real" para el código que se ejecuta en él, aunque requiere sustancialmente menos recursos que este último.
Los subprocesos virtuales permiten decenas de millones de tareas y eventos preventivos en una computadora de consumo de 2021, [1] en comparación con los pocos miles de subprocesos del sistema operativo. [2] La ejecución preventiva [3] es importante para obtener ganancias de rendimiento a través del paralelismo y tiempos de respuesta preventivos rápidos para decenas de millones de eventos.
Las construcciones anteriores que no son o no siempre son preventivas, como las corrutinas , los subprocesos verdes o Node.js , que en gran medida tiene un solo subproceso , introducen demoras en la respuesta a eventos asincrónicos, como cada solicitud entrante en una aplicación de servidor. [4]
Definición
Los hilos virtuales se comercializaron con el navegador Chrome de Google en 2008 [5] , donde los hilos virtuales pueden saltar de hilos físicos. Los hilos virtuales son verdaderamente virtuales, creados en software de espacio de usuario.
- Los hilos virtuales son preventivos
- Esto es importante para el rendimiento de la respuesta, ya que el hilo virtual puede reaccionar a los eventos sin la intervención del programador o antes de concluir una tarea actual.
- La preempción requiere conocimiento de programación multiproceso para evitar escrituras rotas, carreras de datos y escrituras invisibles por parte de otros subprocesos.
- Los subprocesos virtuales pueden saltar sobre las unidades de ejecución de todos los procesadores y núcleos.
- Esto permite utilizar todo el hardware disponible, un aumento de 10 veces en las computadoras actuales.
- En la implementación de go1.18, hay colas de subprocesos virtuales por unidad de ejecución. Hay subprocesos virtuales adicionales que no están asignados a una unidad de ejecución y una unidad de ejecución puede robar subprocesos virtuales de otra unidad de ejecución [6].
- Los hilos virtuales no requieren rendimiento ni intervenciones similares por parte del programador.
- Los subprocesos virtuales parecen ejecutarse continuamente hasta que regresan o se detienen en un bloqueo de sincronización.
- A diferencia de las corrutinas, si un subproceso virtual está en un bucle infinito, no bloquea el programa. La ejecución continúa con una carga de CPU mayor, incluso si hay más subprocesos en bucle que unidades de ejecución disponibles.
- Los hilos virtuales pueden sumar decenas de millones al incluir pequeñas pilas a menudo administradas
- Esto permite varias magnitudes más de subprocesos que si se utilizan subprocesos del sistema operativo.
- Go 1.18 puede lanzar 15 millones de subprocesos virtuales en una computadora de consumo de 2021, es decir, alrededor de 350 000 por gigabyte de memoria principal. Esto es posible gracias a que las goroutines tienen una pila redimensionable de menos de 3 KiB.
- Una computadora de consumo generalmente admite 3000 subprocesos del sistema operativo y, a través de la configuración del sistema, puede ofrecer quizás 15 000.
- Los subprocesos virtuales se pueden asignar rápidamente, de manera similar a la velocidad de las asignaciones de memoria.
- Dado que la asignación de un subproceso virtual es similar a la asignación de estructuras de memoria, se pueden asignar muy rápidamente, quizás 600 000 por segundo. Esto no es posible para subprocesos del sistema operativo que bloquearían el host a una velocidad muy inferior a esta
- La aceleración más rápida reduce la necesidad de grupos de subprocesos de subprocesos previamente lanzados para hacer frente a aumentos repentinos en el tráfico.
- En Go, se asigna un hilo virtual mediante una llamada de función precedida por la palabra clave "go". La llamada de función proporciona un cierre de valores de variables que se garantiza que serán visibles para la nueva goroutine. Las goroutines no tienen valor de retorno, por lo que una goroutine que retorna simplemente desaparece.
- Los subprocesos virtuales comparten el mapa de memoria como los subprocesos del sistema operativo
- Al igual que los subprocesos del sistema operativo, los subprocesos virtuales comparten la memoria en todo el proceso y, por lo tanto, pueden compartir y acceder libremente a objetos de memoria sujetos a sincronización.
- Algunas arquitecturas de un solo subproceso, como el motor ECMAScript V8 utilizado por Node.js, no aceptan fácilmente datos que el subproceso en particular no asignó, lo que requiere el uso de tipos de datos especiales de copia cero cuando se comparten datos entre subprocesos.
- Los hilos virtuales ofrecen paralelismo como los hilos del sistema operativo
- El paralelismo significa que varias instrucciones se ejecutan realmente al mismo tiempo, lo que generalmente conduce a un rendimiento mucho más rápido.
- Esto es diferente de la concurrencia más simple, en la que una sola unidad de ejecución ejecuta múltiples subprocesos compartidos en pequeños incrementos de tiempo. La división en intervalos de tiempo hace que parezca que cada subproceso se está ejecutando continuamente. Si bien la concurrencia es más fácil de implementar y programar, no ofrece ninguna mejora en el rendimiento.
Razones subyacentes
Los servidores Java han incorporado construcciones de software extensas y que consumen mucha memoria, lo que permite que docenas de subprocesos del sistema operativo agrupados ejecuten de manera preventiva miles de solicitudes por segundo sin el uso de subprocesos virtuales. La clave para el rendimiento en este caso es reducir la latencia inicial en el procesamiento de los subprocesos y minimizar el tiempo en que los subprocesos del sistema operativo están bloqueados. [7]
Los subprocesos virtuales aumentan la concurrencia posible en muchos órdenes de magnitud, mientras que el paralelismo real logrado está limitado por las unidades de ejecución disponibles y la segmentación que ofrecen los procesadores y núcleos de procesador actuales. En 2021, las computadoras de consumo suelen ofrecer un paralelismo de decenas de unidades de ejecución simultáneas. [8] Para aumentar el rendimiento a través del paralelismo, el entorno de ejecución del lenguaje debe utilizar todo el hardware presente, [9] no ser de un solo subproceso ni presentar sincronización global como el bloqueo global del intérprete .
El aumento de múltiples magnitudes en los elementos preemptivos posibles que ofrecen los subprocesos virtuales se logra mediante el manejo de pilas de subprocesos redimensionables por parte del entorno de ejecución del lenguaje. [10] Esas pilas son más pequeñas que las de los subprocesos del sistema operativo. La cantidad máxima de subprocesos posibles sin intercambio es proporcional a la cantidad de memoria principal. [11]
Para soportar hilos virtuales de manera eficiente, el tiempo de ejecución del lenguaje debe ser reescrito en gran medida para evitar que las llamadas de bloqueo retengan un hilo del sistema operativo asignado para ejecutar un hilo virtual [12] y para administrar pilas de hilos. [13] Un ejemplo de una modernización de hilos virtuales es Java Loom. [14] Un ejemplo de un nuevo lenguaje diseñado para hilos virtuales es Go. [15]
Complejidad
Debido a que los hilos virtuales ofrecen paralelismo, el programador debe ser experto en programación y sincronización de múltiples subprocesos.
Debido a que un subproceso virtual bloqueado bloquearía el subproceso del sistema operativo que ocupa en ese momento, se debe realizar un gran esfuerzo en tiempo de ejecución para manejar las llamadas de sistema bloqueantes. Normalmente, se utiliza un subproceso de un grupo de subprocesos del sistema operativo de repuesto para ejecutar la llamada de bloqueo para el subproceso virtual, de modo que el subproceso del sistema operativo que se está ejecutando inicialmente no se bloquee.
La gestión de la pila de subprocesos virtuales requiere cuidado en el enlazador y predicciones breves de los requisitos de espacio de pila adicionales.
Implementaciones
Navegador Google Chrome
Los subprocesos virtuales se utilizan para serializar actividades de entrada/salida de un solo hilo. Cuando se ejecuta un subproceso virtual, puede pasar a un subproceso de un sistema operativo diferente. El navegador Chrome apareció por primera vez en 2008. Los subprocesos virtuales de Chrome están disponibles para los desarrolladores que amplían el navegador.
Ir
Las goroutines de Go se volvieron preventivas con Go 1.4 en 2014 y son una aplicación destacada de hilos virtuales.
Java
Java introdujo hilos virtuales en 2023 con JDK 21, con la limitación de que cualquier código que se ejecute en un hilo virtual que use bloques sincronizados o llamadas nativas quedará anclado a su hilo del sistema operativo portador. [16]
Otros usos del término
En 2007, Intel [17] se refirió a una técnica de optimización específica del compilador Intel como subprocesos virtuales.
Véase también
Referencias
- ^ Rudell, Harald (19 de marzo de 2022). "paralelismovirtualmasivo".
- ^ baeldung (2 de enero de 2022). "Número máximo de subprocesos por proceso en Linux | Baeldung en Linux". www.baeldung.com . Consultado el 30 de marzo de 2022 .
- ^ "Notas de la versión de Go 1.14: el lenguaje de programación Go". go.dev . Consultado el 30 de marzo de 2022 .
- ^ Node.js. "No bloquees el bucle de eventos (ni el grupo de trabajadores)". Node.js . Consultado el 30 de marzo de 2022 .
- ^ "Subprocesos y tareas en Chrome". chromium.googlesource.com . Consultado el 5 de abril de 2022 .
- ^ Lu, Genchi (22 de julio de 2021). "Modelo de subprocesos de Java y gorutina de Golang". Medium . Consultado el 5 de abril de 2022 .
- ^ "Principios para manejar miles de conexiones en Java usando Netty - DZone Performance". dzone.com . Consultado el 30 de marzo de 2022 .
- ^ "MacBook Pro de 14 pulgadas y MacBook Pro de 16 pulgadas". Apple . Consultado el 30 de marzo de 2022 .
- ^ "Preguntas frecuentes (FAQ) - El lenguaje de programación Go". go.dev . Consultado el 30 de marzo de 2022 .
- ^ "Borrador de JEP: Hilos virtuales (versión preliminar)". openjdk.java.net . Consultado el 30 de marzo de 2022 .
- ^ Rudell, Harald (22 de marzo de 2022). "Número máximo de subprocesos virtuales en Go".
- ^ Szczukocki, Denis (18 de marzo de 2020). «Diferencia entre subproceso e subproceso virtual en Java | Baeldung». www.baeldung.com . Consultado el 30 de marzo de 2022 .
- ^ "Por qué puedes tener millones de Goroutines pero solo miles de subprocesos Java". rcoh.me . 2018-04-12 . Consultado el 2022-03-30 .
- ^ "Principal - Principal - Wiki de OpenJDK". wiki.openjdk.java.net . Consultado el 30 de marzo de 2022 .
- ^ "El lenguaje de programación Go". go.dev . 2022-03-22 . Consultado el 2022-03-30 .
- ^ "Hilos virtuales". Centro de ayuda de Oracle . Consultado el 10 de septiembre de 2024 .
- ^ "Revista de tecnología Intel" (PDF) .
Enlaces externos
- paralelismovirtual masivo Límites de pruebas de programas Go en subprocesos virtuales