Uso alto de cpu o memoria y aumento de bucles de espera de giro en .NET Framework en máquinas virtuales mediante procesadores Intel Skylake
Este artículo le ayuda a resolver el problema en el que se produce un alto uso de cpu o memoria en aplicaciones de Microsoft .NET Framework en máquinas virtuales de Azure (VM) controladas por procesadores Intel Skylake.
Versión del producto original: .NET Framework
Número KB original: 4527212
Síntomas
Experimenta un uso de cpu o memoria superior al esperado en máquinas virtuales de Azure que se implementaron recientemente en equipos controlados por procesadores Intel Skylake. Según Intel, este cambio afecta al rendimiento de la máquina virtual y a la carga de trabajo general o a la ejecución de aplicaciones.
El problema se debe a un aumento en el retraso de instrucciones de pausa para procesadores Intel Skylake. Es posible que observe este problema especialmente en .NET Framework aplicaciones. Esto se debe a que el cambio pausar latencia afecta a los bucles de giro y espera largos que son comunes en .NET Framework.
Causa
En la microarquitectura skylake más reciente, Intel aumentó el valor de latencia de pausa hasta 140 ciclos. En la microarquitectura de generación anterior, el valor de latencia de pausa es de unos 10 ciclos. Según Intel, este cambio se realizó para mejorar el uso compartido de recursos. Para obtener más información sobre el cambio y sus efectos, vea la sección 8.4.7 del siguiente documento PDF de Intel: Intel 64 e IA-32 Architectures Optimization Reference Manual.
Solución
Importante
Siga atentamente los pasos de esta sección. La modificación incorrecta del Registro puede producir graves problemas. Antes de modificarlo, realice una copia de seguridad del Registro para efectuar una restauración en caso de que surjan problemas.
Corrección de este problema
Para solucionar este problema, instale .NET Framework de seguridad y calidad de octubre de 2018.
Nota
En .NET Framework 4.8, la corrección está habilitada de forma predeterminada. En .NET Framework 4.6.x y 4.7.x, la corrección está deshabilitada de forma predeterminada y se puede habilitar manualmente.
Para habilitar la corrección del retraso de pausa en procesadores Skylake, inicie el Editor del Registro y agregue la clave como valor Thread_NormalizeSpinWait DWORD a la siguiente subclave:
- Ubicación:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework - Nombre del valor:
Thread_NormalizeSpinWait - Datos de valor: 1
Nota
Otras aplicaciones de cliente también pueden verse afectadas por la configuración del temporizador, aunque esta configuración no está habilitada de forma predeterminada en ninguna versión de .NET Framework. Si el rendimiento de la carga de trabajo aún se ve afectado después del cambio de latencia de pausa, tenga en cuenta si los temporizadores son una fuente significativa de contención de bloqueo. Si determina que esto es true, vaya a la sección Corrección para los temporizadores.
Corrección de los temporizadores
Para habilitar manualmente la corrección, agregue la Switch.System.Threading.UseNetCoreTimer clave como valor string a la siguiente subclave:
- Ubicación:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AppContext - Nombre del valor:
Switch.System.Threading.UseNetCoreTimer - Datos de valor: true
Para obtener más información acerca de los temporizadores, vea la sección AppContext para consumidores de biblioteca en Clase AppContext.
Preguntas frecuentes
¿Este cambio causa algún daño si también tenemos UseNetCoreTimer habilitado en todo tipo de hardware?
La corrección del temporizador no está habilitada actualmente de forma predeterminada en ninguna versión de .NET Framework. No se recomienda cambiar la configuración predeterminada en el nivel local.
¿Hay otros problemas conocidos causados por el cambio de latencia de pausa en Skylake?
La nueva medida Pausar latencia también consume tiempo de CPU adicional durante el inicio. Normalmente, el valor es de unos 10 ms de tiempo de CPU. La duración aumentada se considera necesaria para obtener medidas más confiables y mejorar la capacidad de solucionar el problema. Sin embargo, .NET Framework aplicaciones también pueden ser herramientas de ejecución corta. El uso frecuente de estas herramientas puede provocar un mayor uso de LA CPU que antes de aplicar la corrección. Esto se consideró como una negociación aceptable para solucionar un problema mayor y habilitar la corrección de forma predeterminada en .NET Framework 4.8.
¿Se garantiza que la corrección de latencia de pausa de Skylake resuelva mi problema?
No, la corrección no está garantizada. Podría haber otros elementos no relacionados fuera de este problema que afecten al rendimiento específico de la carga de trabajo. La eficacia de la corrección se encuentra en la calidad de la medida. Hay límites en uso para asegurarse de que no sobreescalemos los recuentos de giros en .NET Framework. Sin embargo, pueden producirse medidas malas cuando la máquina virtual está muy cargada. Esto puede impedir que la corrección sea eficaz. En el peor de los casos (excluyendo la contraoferta que se menciona en A2), esta situación sería similar a la corrección que no se aplica.
¿Tenemos alguna guía para los ingenieros de soporte técnico sobre cómo podemos detectar que cualquier problema de rendimiento percibido se debe a este cambio?
Para determinar esto, genera una generación de perfiles de la aplicación que se usa. La comparación de perfiles que tienen cargas similares entre una máquina virtual basada en Skylake y una máquina virtual basada en Skylake puede mostrar mucho más tiempo invertido relativamente en la VM
clr!AwareLock::Contentionde Skylake. Esto indicaría que la corrección de retraso de pausa sería útil si la máquina virtual se ejecuta en un procesador Skylake.
Para la corrección del temporizador, la pila de llamadas mostraría clr!AwareLock::Contention que se llama mediante mscorlib.ni!System.Threading.TimerQueueTimer.Fire() . Si el Fire() método u otros métodos en son el origen principal de la contención, esto indicaría que la corrección del temporizador sería de TimerQueueTimer ayuda.
También es posible supervisar las tasas de contención de bloqueo mediante el Monitor de rendimiento. Para obtener más información, vea las entradas Tasa de contención / Sec y Total # de contención para .NET CLR LocksAndThreads en la sección Contadores de rendimiento de subprocesos y bloqueo en Contadores de rendimiento en el .NET Framework.
Aviso de declinación de responsabilidades sobre la información de terceros
Los productos de otros fabricantes que se mencionan en este artículo han sido creados por compañías independientes de Microsoft. Microsoft no ofrece ninguna garantía, ya sea implícita o de otro tipo, sobre la confiabilidad o el rendimiento de dichos productos.