linux - tag - ¿Cuál es la sobrecarga de un cambio de contexto?
ubuntu mp3 tag editor (3)
Como sabe wikipedia en su artículo de Cambio de contexto , "el cambio de contexto es el proceso de almacenamiento y restauración del estado (contexto) de un proceso para que la ejecución se pueda reanudar desde el mismo punto en un momento posterior ". Asumiré el cambio de contexto entre dos procesos del mismo sistema operativo, no la transición de modo usuario / kernel (syscall), que es mucho más rápida y no necesita una descarga TLB.
Por lo tanto, se necesita mucho tiempo para que el kernel del sistema operativo guarde el estado de ejecución (todos, en realidad todos los registros; y muchas estructuras de control especiales) del proceso actual en ejecución en la memoria, y luego cargue el estado de ejecución de otro proceso (leído desde la memoria) . La descarga TLB, si es necesario, agregará algo de tiempo al interruptor, pero es solo una pequeña parte de la sobrecarga total.
Si desea encontrar la latencia del cambio de contexto, existe la herramienta de referencia lmbench
http://www.bitmover.com/lmbench/ con la prueba LAT_CTX http://www.bitmover.com/lmbench/lat_ctx.8.html
No puedo encontrar resultados para nehalem (¿existe lmbench en phoronix suite?), Pero para Core2 y el cambio de contexto de Linux moderno pueden costar entre 5 y 7 microsegundos.
También hay resultados para la prueba de baja calidad http://blog.tsunanet.net/2010/11/how-long-does-it-take-to-make-context.html con 1-3 microsegundos para cambio de contexto. No se puede obtener el efecto exacto de no descargar el TLB de sus resultados.
ACTUALIZACIÓN : su pregunta debe ser sobre la virtualización, no sobre el cambio de contexto de proceso.
RWT dice en su artículo sobre Nehalem "Dentro de Nehalem: el procesador y sistema futuros de Intel. TLB, tablas de páginas y sincronización", el 2 de abril de 2008 por David Kanter, que Nehalem agregó VPID a la TLB para hacer conmutadores de máquina / host virtual (vmentry / vmexit ) Más rápido:
Las entradas de TLB de Nehalem también han cambiado sutilmente al introducir una "ID de procesador virtual" o VPID. Cada entrada de TLB almacena en caché una traducción de dirección virtual a física ... esa traducción es específica para un proceso y una máquina virtual dados. Las CPU más antiguas de Intel descargarían los TLB cada vez que el procesador cambiara entre el invitado virtualizado y la instancia del host, para garantizar que los procesos solo accedieran a la memoria a la que podían tocar. El VPID rastrea a qué VM se asocia una entrada de traducción determinada en el TLB, de modo que cuando se produce una salida y reingreso de la VM, los TLB no tienen que vaciarse por seguridad. .... El VPID es útil para el rendimiento de la virtualización al reducir la sobrecarga de las transiciones de VM; Intel estima que la latencia de una transición de VM de ida y vuelta en Nehalem es del 40% en comparación con Merom (es decir, el Core 2 de 65nm) y aproximadamente un tercio más bajo que el Penryn de 45nm.
Además, debe saber que en el fragmento citado por usted en la pregunta, el enlace "[18]" era "G. Neiger, A. Santoni, F. Leung, D. Rodgers y R. Uhlig. Intel Virtualización Tecnología: Soporte de hardware para la virtualización eficiente de procesadores . Intel Technology Journal, 10 (3). ", Por lo que esta es una característica para una virtualización efectiva (conmutadores rápidos de host-huésped).
Originalmente creía que la sobrecarga a un cambio de contexto era el TLB que se estaba vaciando. Sin embargo, acabo de ver en wikipedia:
http://en.wikipedia.org/wiki/Translation_lookaside_buffer
En 2008, tanto Intel (Nehalem) [18] como AMD (SVM) [19] introdujeron etiquetas como parte de la entrada de TLB y hardware dedicado que verifica la etiqueta durante la búsqueda. A pesar de que estos no están totalmente explotados, se prevé que en el futuro, estas etiquetas identificarán el espacio de direcciones al que pertenece cada entrada de TLB. Por lo tanto, un cambio de contexto no provocará el vaciado del TLB , sino que simplemente cambiará la etiqueta del espacio de direcciones actual a la etiqueta del espacio de direcciones de la nueva tarea.
¿Se confirma lo anterior para las nuevas CPU de Intel que el TLB no se vacía en los cambios de contexto?
¿Esto significa que no hay gastos generales reales ahora en un cambio de contexto?
(Estoy tratando de entender la penalización de rendimiento de un cambio de contexto)
Rompamos el costo de un cambio de tarea en "costos directos" (el costo del propio código de cambio de tarea) y "costos indirectos" (costos de TLB, etc.).
Costos directos
Para costos directos, este es principalmente el costo de guardar el estado (visible desde el punto de vista arquitectónico para el espacio del usuario) para la tarea anterior y luego cargar el estado para la próxima tarea. Esto varía según la situación, principalmente porque puede o no incluir el estado de FPU / MMX / SSE / AVX que puede agregar hasta varios KiB de datos (especialmente si AVX está involucrado, por ejemplo, AVX2 tiene 512 bytes por sí mismo y AVX- 512 es más de 2 KiB por sí mismo).
Tenga en cuenta que existe un mecanismo de "carga perezosa" para evitar el costo de la carga (algunos o todos) del estado FPU / MMX / SSE / AVX, y evitar el costo de guardar ese estado si no se cargó; y esta función se puede deshabilitar por razones de rendimiento (si casi todas las tareas utilizan el estado, entonces el costo de un "estado en uso se debe cargar" la captura / excepción excede lo que se ahorra al tratar de evitar hacerlo durante el cambio de tarea) o por razones de seguridad (por ejemplo, porque el código en Linux "guarda si se usa" y no "guarda luego borra si se usa" y deja los datos que pertenecen a una tarea en registros que pueden obtenerse mediante una tarea diferente a través de ataques de ejecución especulativa).
También existen otros costos (actualización de estadísticas, por ejemplo, "cantidad de tiempo de CPU utilizado por la tarea anterior"), que determina si la nueva tarea utiliza el mismo espacio de direcciones virtuales que la tarea anterior (por ejemplo, un subproceso diferente en el mismo proceso), etc.
Costos indirectos
Los costos indirectos son esencialmente la pérdida de efectividad para todas las cosas "similares a caché" que tiene la CPU: los cachés en sí mismos, los TLB, los cachés de estructura de paginación de nivel superior, todo el material de predicción de bifurcación (dirección de bifurcación, destino de bifurcación, búfer de retorno), etc. .
Los costos indirectos se pueden dividir en 3 causas. Uno es el costo indirecto que se produce porque el interruptor de tarea limpió completamente la cosa. En el pasado, esto se limitaba principalmente a los fallos de TLB causados porque los TLB se vaciaban durante el cambio de tarea. Tenga en cuenta que esto puede suceder incluso cuando se utiliza PCID: hay un límite de 4096 ID (y cuando se usa la "mitigación de fusión" las ID se usan en pares) para cada espacio de direcciones virtuales, se utiliza una ID para el espacio de usuario y otra para kernel), lo que significa que cuando se usan más de 4096 (o 2048) espacios de direcciones virtuales, el kernel tiene que reciclar los ID utilizados anteriormente y vaciar todos los TLB para el ID que se está reutilizando. Sin embargo, ahora (con todos los problemas de seguridad de ejecución especulativa) el kernel puede vaciar otras cosas (por ejemplo, cosas de predicción de ramificación) para que la información no pueda pasar de una tarea a otra, pero realmente no sé si Linux lo hace o no lo hace. Admite esto para lo que "me gusta" (y sospecho que principalmente intentan evitar que los datos se filtren del kernel al espacio de usuario y terminan evitando que los datos se filtren de una tarea a otra por accidente).
Otra causa de costos indirectos son los límites de capacidad. Por ejemplo, si el caché L2 solo es capaz de almacenar en caché un máximo de 256 KiB de datos y la tarea anterior utilizó más de 256 KiB de datos; entonces el caché L2 estará lleno de datos que no sirven para la siguiente tarea y todos los datos que la próxima tarea que quiera que se almacenen en la memoria caché (y que anteriormente se almacenaron en la memoria caché) se desalojarán debido a que "se usó menos recientemente". Esto se aplica a todas las cosas "similares a caché" (incluidos los TLB y los cachés de estructura de paginación de nivel superior, incluso cuando se utiliza la función PCID).
La otra causa de los costos indirectos es migrar una tarea a una CPU diferente. Esto depende de qué CPU, por ejemplo, si la tarea se migra a una CPU lógica diferente dentro del mismo núcleo, entonces ambas CPU pueden compartir muchas cosas "similares a caché" y los costos de migración pueden ser relativamente pequeños; y si la tarea se migra a una CPU en un paquete físico diferente, ninguna de las cosas "similares a caché" puede ser compartida por ambas CPU y los costos de migración pueden ser relativamente grandes.
Tenga en cuenta que el límite superior para la magnitud de los costos indirectos depende de lo que haga la tarea. Por ejemplo, si una tarea utiliza una gran cantidad de datos, los costos indirectos pueden ser relativamente costosos (gran cantidad de caché y TLB faltan), y si la tarea utiliza una cantidad pequeña de datos, los costos indirectos pueden ser insignificantes (muy poca memoria caché y TLB pierde).
No relacionado
Tenga en cuenta que la función PCID tiene sus propios costos (no relacionados con los propios conmutadores de tareas). Específicamente; cuando las traducciones de páginas se modifican en una CPU, es posible que deban ser invalidadas en otras CPU utilizando algo llamado "derribo de TLB de múltiples CPU", que es relativamente costoso (implica una Interrupción de IPI / Interprocesador que interrumpe otras CPU y cuesta "cientos de cientos" de ciclos "por CPU). Sin PCID puedes evitar algunos de estos. Por ejemplo, sin PCID, para un proceso de un solo subproceso que se ejecuta en una CPU, sabe que ninguna otra CPU puede usar el mismo espacio de direcciones virtuales y, por lo tanto, sabe que no necesita hacer el "downdown TLB de múltiples CPU". ", y si un proceso de subprocesos múltiples está limitado a un solo dominio NUMA, solo las CPU dentro de ese dominio NUMA deben participar en el" disparo de TLB de múltiples CPU ". Cuando se utiliza PCID, no puede confiar en estos trucos y tiene una sobrecarga mayor porque la "reducción de TLB de varias CPU" no se evita tan a menudo.
Por supuesto, también hay un costo asociado con la administración de ID (por ejemplo, averiguar qué ID es libre de asignar a una tarea recién creada, revocar ID cuando se terminan las tareas, algún tipo de sistema "menos usado recientemente" para volver a proponer ID cuando hay más espacios de direcciones virtuales que los identificadores, etc).
Debido a estos costos, es probable que haya casos patológicos en los que el costo de usar PCID exceda los beneficios de "menos errores de TLB causados por los conmutadores de tareas" (donde el uso de PCID empeora el rendimiento).
Si contamos en la invalidación de la memoria caché (que normalmente deberíamos, y que es el Mayor Contribuidor para los costos del cambio de contexto en el mundo real), la penalización del rendimiento debido al cambio de contexto puede ser ENORME:
https://www.usenix.org/legacy/events/expcs07/papers/2-li.pdf (es cierto que está un poco desactualizado, pero lo mejor que pude encontrar) lo ofrece en el rango de los ciclos de CPU de 100K-1M. Teóricamente, en el peor de los casos posible para una caja de servidor con múltiples zócalos con 32M L3 de cachés por socket que consisten en líneas de caché de 64 bytes, acceso completamente aleatorio y tiempos de acceso típicos de 40 ciclos para L3 / 100 ciclos para la RAM principal , la penalización puede alcanzar hasta 30M + ciclos de CPU (!).
Por experiencia personal, diría que generalmente está en el rango de decenas de ciclos de K, pero según las especificaciones, puede diferir en un orden de magnitud.