Desempenho de CPU baixo em VMs Hyper‑V no Windows Server 2022: diagnóstico e solução com HwThreadCountPerCore

Viu a CPU das suas VMs Hyper‑V despencar após migrar para o Windows Server 2022? Você não está sozinho. Este guia prático explica a causa, mostra como diagnosticar e traz passos objetivos para recuperar o desempenho — sem desativar o Hyper‑Threading no host.

Índice

Visão geral do problema

Um cenário recorrente após a atualização de clusters do Windows Server 2016 para 2022 é a queda de desempenho de CPU dentro das VMs quando comparadas ao host físico. Exemplos típicos:

  • Teste de um único núcleo: cerca de 200 no host versus 120 dentro da VM.
  • Teste limitado a quatro vCPU: host em torno de 730 e VM por volta de 360.
  • Alertas de CPU Wait Time per Dispatch com picos entre 50–80 µs.

Em hosts novos com Hyper‑Threading (HT) ativado, um detalhe chama a atenção: ao atribuir “4 vCPU” à VM, o convidado passa a enxergar isso como 2 núcleos e 4 threads — e não como 4 núcleos “puros”. Em determinadas cargas que escalam melhor por núcleo do que por thread (SMT), isso degrada o desempenho percebido.

Por que isso acontece no Windows Server mais recente

A partir do Windows Server 2019, o Hyper‑V adota por padrão o core scheduler. Esse agendador herdou e reforçou uma filosofia de segurança e previsibilidade: a topologia SMT/HT do host passa a ser refletida para dentro das VMs. Isso significa que:

  • Várias VMs (especialmente criadas ou atualizadas em hosts 2019/2022) têm o parâmetro HwThreadCountPerCore em 0, que significa “herdar do host”.
  • Se o host possui 2 threads por núcleo (HT ativo), 4 vCPU tendem a ser apresentadas ao convidado como 2 cores × 2 threads.
  • Em cargas CPU‑bound que não extraem ganho adequado de SMT (por exemplo, muitos bancos de dados e aplicativos licenciados por vCore), essa topologia reduz o desempenho por vCPU quando comparada à visão de 4 núcleos × 1 thread.

No Windows Server 2016, o comportamento padrão era diferente: a maior parte das VMs operava como se não houvesse SMT, entregando 1 thread por núcleo. A mudança de padrão entre as versões explica por que, após o upgrade, o mesmo conjunto de vCPU passou a performar abaixo do esperado.

Solução direta para a maioria dos casos

Em vez de desligar o Hyper‑Threading no host — o que sacrifica capacidade de cluster para todas as VMs — prefira controlar o SMT por VM com o parâmetro HwThreadCountPerCore. Assim, você pode ter VMs críticas com “núcleos puros” ao lado de VMs que continuam explorando SMT quando isso fizer sentido.

Passo a passo essencial

  1. Forçar “vCPU = núcleos puros” apenas onde interessa# Ver a configuração atual (Get-VMProcessor -VMName "MinhaVM").HwThreadCountPerCore Forçar 1 thread por núcleo (sem SMT) → 4 vCPU = 4 núcleos expostos Set-VMProcessor -VMName "MinhaVM" -HwThreadCountPerCore 1Notas rápidas:
    • 0 = herdar do host; 1 = sem SMT; valores >1 definem threads por núcleo.
    • No Windows Server 2016 não há suporte para “herdar” (0), mas 1 funciona normalmente.
    • Faça desligamento e novo início da VM após alterar a topologia, garantindo que o convidado renegocie o layout da CPU. Migrações ao vivo podem sustentar a topologia anterior até um boot a frio.
  2. Atualizar a versão de configuração da VM (recomendado para VMs trazidas do 2016) Get-VM | Format-Table Name, Version Com a VM desligada: Update-VMVersion -VMName "MinhaVM" Isso não muda a topologia por si só, mas desbloqueia recursos e comportamentos modernos do host.
  3. Confirmar que o host usa o core scheduler (padrão no 2019+) Get-WinEvent -FilterHashTable @{ProviderName="Microsoft-Windows-Hyper-V-Hypervisor"; ID=2} -MaxEvents 1 Se precisar ajustar, sabendo dos impactos: bcdedit /set hypervisorschedulertype core shutdown /r /t 0
  4. Interpretar corretamente “CPU Wait Time per Dispatch” Esse contador mede o tempo que um vCPU espera até ser despachado a um processador lógico. Picos na casa de 50–80 µs costumam cruzar limiares de alerta padrão, mas o que interessa é a tendência longitudinal. Observe janelas mais longas e trate valores persistentemente altos (por exemplo, >100 µs por longos períodos) como sinal de contenção real.
  5. Garantir base sólida no host
    • Plano de energia em Alto desempenho (evita core parking e latências de economia agressiva).
    • BIOS e firmware atualizados; desativar C‑states profundos quando a latência for prioritária.
    • Evitar oversubscription excessiva de vCPU em hosts carregados.

Diagnóstico aprofundado

Além de aplicar a solução, vale confirmar como a topologia está chegando ao convidado, acompanhar métricas relevantes e entender se seu perfil de carga se beneficia de SMT. Use as técnicas abaixo para reduzir a adivinhação.

Como ver a topologia de CPU da VM

Get-VMProcessor -VMName "MinhaVM" | Select-Object VMName, Count, HwThreadCountPerCore

No convidado Windows, confira em Gerenciador de Tarefas → Desempenho se o sistema exibe “lógicos” em dobro (indicando threads por núcleo). Em Linux, veja lscpu e compare “cores per socket” e “threads per core”.

PerfMon e contadores que importam

  • Hyper‑V Hypervisor Virtual ProcessorCPU Wait Time per Dispatch: latência de despacho por vCPU.
  • Hyper‑V Hypervisor Logical ProcessorTotal Run Time e % Total Run Time: saturação por CPU lógica do host.
  • Process e Processor no convidado: tempo de usuário vs. kernel e presença de ready time alto.

Se o “Wait Time” sobe sem saturar lógicas do host, suspeite de topologia desfavorável (vCPU agrupadas no mesmo núcleo físico via SMT) e teste HwThreadCountPerCore 1.

Quando usar SMT na VM e quando evitar

Perfil de cargaRecomendação de topologiaJustificativa
Banco de dados com licenciamento por vCoreSem SMT na VM (HwThreadCountPerCore 1)Melhor desempenho por licença e previsibilidade por núcleo.
Aplicações altamente multithread e CPU‑bound (encode, render, build)Testar com e sem SMTAlgumas cargas ganham com SMT; outras sofrem por contendas de recursos internos.
Workloads sensíveis a latênciaSem SMT na VMReduz preempções e partilha do núcleo físico com sibling.
Servidores mistos e pouco CPU‑boundHerdar do host (0)Economia de configuração e aproveitamento de SMT quando oportuno.

Boas práticas adicionais no Hyper‑V

  • vNUMA coerente: mantenha vCPU e memória da VM dentro de limites que respeitem fronteiras NUMA do host. Excesso pode aumentar latências de memória.
  • Dynamic Memory: para cargas CPU‑bound, considere memória estática para evitar quedas por ballooning em momentos críticos.
  • Affinity e grupos de processadores: raramente necessários; deixe o core scheduler fazer o trabalho, a menos que exista razão clara para fixar vCPUs.
  • Compatibilidade de processador: habilite apenas quando precisar de Live Migration entre gerações diferentes de CPU; há impacto em instruções avançadas.

Como validar que a correção funcionou

  1. Antes: meça no host e na VM cenários comparáveis (por exemplo, teste de um único thread e teste de 4 vCPU).
  2. Aplique: defina HwThreadCountPerCore 1 na VM alvo e faça desligamento e novo início.
  3. Depois: repita os testes. Em workloads que escalam melhor por núcleo, é comum ver a VM aproximar‑se do host (ganhos expressivos em testes de até 4 vCPU).
  4. Observe: o CPU Wait Time per Dispatch deve reduzir na média, com menos picos em momentos de carga.

Automação com PowerShell

Inventário de topologia das VMs

Get-VM | ForEach-Object {
  $p = Get-VMProcessor -VMName $_.Name
  [PSCustomObject]@{
    VM            = $_.Name
    vCPU          = $p.Count
    ThreadsPorNuc = $p.HwThreadCountPerCore
  }
} | Sort-Object VM | Format-Table -AutoSize

Aplicar “núcleos puros” a um conjunto de VMs

$alvo = Get-VM | Where-Object {$_.Name -match "PRD-|SQL-"}
foreach($vm in $alvo){
  Write-Host "Ajustando $($vm.Name)..." -ForegroundColor Cyan
  Set-VMProcessor -VMName $vm.Name -HwThreadCountPerCore 1
}
Write-Host "Concluído. Faça shutdown/start das VMs alteradas." -ForegroundColor Green

Checar rapidamente o tipo de escalonador

$evt = Get-WinEvent -FilterHashTable @{ProviderName="Microsoft-Windows-Hyper-V-Hypervisor"; ID=2} -MaxEvents 1
$evt | Select-Object TimeCreated, Message

Colocar o host em Alto desempenho

powercfg /setactive SCHEME_MIN  # Ativa o esquema "Alto desempenho"
Opcional: desativar suspensão seletiva em servidores
powercfg /change monitor-timeout-ac 0
powercfg /hibernate off

Entendendo o contador CPU Wait Time per Dispatch

Esse indicador, do ponto de vista do hypervisor, captura o tempo ocioso à espera de CPU física para cada vCPU. Alguns pontos práticos:

  • Picos não contam a história toda: explosões momentâneas de 50–80 µs são comuns; use janelas contínuas para avaliar.
  • Olhe o conjunto: correlacione com % Total Run Time das lógicas do host e com o ready time no convidado.
  • Ajustes que ajudam: reduzir oversubscription, alinhar o plano de energia, aplicar HwThreadCountPerCore 1 em cargas sensíveis e controlar vNUMA.

Impacto em licenciamento por vCore

Em VMs licenciadas por vCore (ex.: bancos de dados), a contagem considera exatamente os vCPU atribuídos. O modo como a VM enxerga a topologia (2C/4T ou 4C/4T) não muda a quantidade de licenças exigidas — mas altera o desempenho por licença. Definir HwThreadCountPerCore 1 tende a alinhar o resultado com a expectativa de “quatro núcleos reais”.

Checklist de correção

  • Definir HwThreadCountPerCore 1 nas VMs críticas e reiniciar a frio.
  • Atualizar a versão de configuração das VMs herdadas do 2016.
  • Confirmar que o host usa core scheduler.
  • Colocar o host em Alto desempenho e revisar BIOS/firmware.
  • Monitorar a tendência do CPU Wait Time per Dispatch, não apenas picos.
  • Manter os Integration Services atualizados via Windows Update nos convidados suportados.

Perguntas frequentes

Desativar HT no host resolve? Sim, mas é uma marreta: reduz a capacidade total e afeta todas as VMs. Use o controle por VM via HwThreadCountPerCore e preserve flexibilidade.

Por que meu teste de um único núcleo caiu tanto? O agendador e a herança de topologia alteram como o hypervisor particiona o tempo do núcleo físico. Em cenários single‑thread, qualquer disputa adicional ou mapeamento desfavorável pode ser amplificada. A configuração sem SMT por VM costuma recuperar esse teste.

Depois de migrar uma VM, o valor parecia não aplicar. É normal? Sim. Após Live Migration, a “topologia efetiva” pode persistir até um boot a frio. Desligue e ligue a VM.

Linux também é afetado? O princípio é o mesmo: a VM herda threads por núcleo e o agendador do convidado decide como escalar. Use lscpu e teste com e sem SMT exposto.

E se eu quiser o inverso, mais threads por núcleo? É possível definir valores >1 em HwThreadCountPerCore quando o host tiver SMT. Faça testes A/B, pois ganhos variam por carga.

Exemplo de análise antes e depois

MétricaAntesDepoisObservação
Benchmark de um núcleo~120~200Recupera a paridade com o host para cargas single‑thread.
Benchmark com quatro vCPU~360~700+Com 4 núcleos “puros”, escala melhor do que 2C/4T.
CPU Wait Time per Dispatch50–80 µs (picos)Menores e menos frequentesMais estabilidade de latência sob carga.

Roteiro de decisão

SintomaProvável causaAção sugeridaRisco
VM com metade do desempenho do host com 4 vCPUTopologia herdada como 2C/4TDefinir HwThreadCountPerCore 1 e reiniciar a frioMenor aproveitamento de SMT para apps que o utilizam bem
Picos de 60–80 µs de Wait TimeLimiares conservadores de alertaAnalisar tendência; otimizar plano de energia e SMT por VMIgnorar tendências sustentadas pode ocultar contenção real
Queda após migração ao vivoTopologia efetiva não refeitaDesligar e ligar a VMJanela curta de indisponibilidade
Licenciamento por vCore desalinhadoSMT exposto sem ganho proporcionalUsar núcleos puros por VM críticaPossível throughput menor em workloads pró‑SMT

Glossário rápido

  • vCPU: unidade de CPU virtual atribuída à VM.
  • SMT/HT: múltiplos threads por núcleo físico.
  • Core scheduler: agendador que mantém afinidade de vCPUs de uma VM ao mesmo núcleo físico para melhorar isolamento e previsibilidade.
  • Wait Time per Dispatch: tempo que um vCPU aguarda para ser executado por um processador lógico.
  • vNUMA: topologia NUMA exposta à VM, impactando latência de memória e escalabilidade.

Conclusão

O salto do Windows Server 2016 para 2022 trouxe ajustes importantes no Hyper‑V, especialmente na forma como a topologia de CPU é exposta às VMs. Em muitas cargas, herdar SMT do host converte “4 vCPU” em “2 núcleos e 4 threads”, o que explica benchmarks inferiores e aumento perceptível de latências. A boa notícia é que o controle está nas suas mãos: defina HwThreadCountPerCore 1 nas VMs certas, faça um ciclo de desligamento e novo início, mantenha o host afinado e atualize a versão de configuração quando aplicável. Na prática, isso devolve o desempenho coerente com o hardware e com o licenciamento por vCore — sem penalizar o cluster todo ao desativar o Hyper‑Threading no host.

Dica final: trate esse ajuste como um perfil por VM. Para bancos de dados e serviços críticos, núcleos “puros” costumam vencer. Para cargas massivamente paralelas, teste com e sem SMT exposto e escolha com base em métricas — não em suposições.

Índice