Compartilhar via


Alto uso de CPU ou memória e aumento de loops de rotação-espera no .NET Framework em VMs usando processadores Intel Skylake

Este artigo ajuda você a resolver o problema em que ocorre alto uso de CPU ou memória em aplicativos Microsoft .NET Framework em VMs (máquinas virtuais) do Azure que são controladas por processadores Intel Skylake.

Versão original do produto: .NET Framework
Número original do KB: 4527212

Sintomas

Você experimenta um uso de CPU ou memória maior do que o esperado em VMs do Azure que foram implantadas recentemente em computadores controlados por processadores Intel Skylake. De acordo com a Intel, essa mudança afeta o desempenho da VM e a carga de trabalho geral ou a execução do aplicativo.

O problema é causado por um aumento no atraso da instrução de pausa para processadores Intel Skylake. Você pode observar esse problema especialmente em aplicativos .NET Framework. Isso ocorre porque a alteração Pausar Latência afeta longos loops de rotação e espera que são comuns no .NET Framework.

Motivo

Na microarquitetura Skylake mais recente, a Intel aumentou o valor de Latência de pausa para até 140 ciclos. Na microarquitetura de geração anterior, o valor de Latência de Pausa é de cerca de 10 ciclos. De acordo com a Intel, essa mudança foi feita para melhorar o compartilhamento de recursos. Para obter mais informações sobre a alteração e seus efeitos, consulte a seção 2.6.4 (Pausar latência na microarquitetura do cliente Skylake) do seguinte documento PDF da Intel: Manual de referência de otimização das arquiteturas Intel 64 e IA-32.

Resolução

Importante

Siga as etapas nesta seção com cuidado. Problemas sérios podem ocorrer se você modificar o registro incorretamente. Antes de modificá-lo, faça um backup do registro para restauração caso ocorram problemas.

Correção para esse problema

Para corrigir esse problema, instale o Pacote Cumulativo de Segurança e Qualidade de outubro de 2018 do .NET Framework.

Observação

No .NET Framework 4.8, a correção é habilitada por padrão. No .NET Framework 4.6.x e 4.7.x, a correção está desabilitada por padrão e pode ser habilitada manualmente.

Para habilitar a correção para o atraso de pausa nos processadores Skylake, inicie o Editor do Registro e adicione a Thread_NormalizeSpinWait chave como um valor DWORD à seguinte subchave:

  • Local: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework
  • Nome do valor: Thread_NormalizeSpinWait
  • Dados do valor: 1

Observação

Outros aplicativos do cliente também podem ser afetados pela configuração do temporizador, mesmo que essa configuração não esteja habilitada por padrão em nenhuma versão do .NET Framework. Se o desempenho da carga de trabalho ainda for afetado após a alteração da latência de pausa, considere se os temporizadores são uma fonte significativa de contenção de bloqueio. Se você determinar que isso é verdade, vá para a seção Corrigir para os temporizadores .

Correção para os temporizadores

Para habilitar manualmente a correção, adicione a Switch.System.Threading.UseNetCoreTimer chave como um valor String à seguinte subchave:

  • Local: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AppContext
  • Nome do valor: Switch.System.Threading.UseNetCoreTimer
  • Dados de valor: true

Para obter mais informações sobre temporizadores, consulte a seção AppContext para consumidores de biblioteca em Classe AppContext.

Perguntas frequentes

  • Essa mudança causa algum dano se também tivermos o UseNetCoreTimer habilitado em todos os tipos de hardware?

    A correção do temporizador não está habilitada atualmente por padrão em nenhuma versão do .NET Framework. Não recomendamos que você altere a configuração padrão no nível local.

  • Existem outros problemas conhecidos causados pela alteração da latência de pausa no Skylake?

    A nova medição de latência de pausa também consome tempo adicional de CPU durante a inicialização. Normalmente, o valor é de cerca de 10 ms de tempo de CPU. O aumento da duração é considerado necessário para obter medições mais confiáveis e melhorar a capacidade de corrigir o problema. No entanto, os aplicativos .NET Framework também podem ser ferramentas de execução curta. O uso frequente de tais ferramentas pode causar maior uso da CPU do que antes da aplicação da correção. Isso foi considerado uma compensação aceitável para corrigir um problema maior e habilitar a correção por padrão no .NET Framework 4.8.

  • A correção da latência de pausa do Skylake é garantida para resolver meu problema?

    Não, a correção não é garantida. Pode haver outros elementos não relacionados fora desse problema que afetam o desempenho de uma carga de trabalho específica. A eficácia da correção depende da qualidade da medição. Há limites em uso para garantir que não superdimensionemos as contagens de rotação no .NET Framework. No entanto, medições incorretas podem ocorrer quando a VM está muito carregada. Isso pode impedir que a correção seja eficaz. No pior caso (excluindo a compensação mencionada em A2), essa situação seria semelhante à correção que não está sendo aplicada.

  • Temos alguma orientação para engenheiros de suporte sobre como podemos detectar que qualquer problema de desempenho percebido é causado por essa alteração?

    Você pode determinar isso criando o perfil do aplicativo usado. A comparação de perfis que têm cargas semelhantes entre uma VM pré-Skylake e uma VM baseada em Skylake pode mostrar muito mais tempo relativamente gasto clr!AwareLock::Contention na VM Skylake. Isso indicaria que a correção do atraso de pausa seria útil se a VM fosse executada em um processador Skylake.

Para a correção do temporizador, a pilha de chamadas mostraria que clr!AwareLock::Contention é chamada por mscorlib.ni!System.Threading.TimerQueueTimer.Fire(). Se o Fire() método ou outros métodos forem TimerQueueTimer a principal fonte de contenção, isso indicaria que a correção do temporizador ajudaria.

Também é possível monitorar as taxas de contenção de bloqueio usando o Monitor de Desempenho. Para obter mais informações, consulte as entradas Taxa de Contenção/s e Total # de Contenções para LocksAndThreads do .NET CLR na seção Contadores de desempenho de bloqueio e thread em Contadores de Desempenho no .NET Framework.

Aviso de isenção de responsabilidade por informações de terceiros

Os produtos de terceiros que este artigo aborda são fabricados por empresas independentes da Microsoft. A Microsoft não oferece nenhuma garantia, expressa ou implícita, sobre o desempenho ou a confiabilidade desses produtos.