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.
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
- 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 1
Notas 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
), mas1
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.
- 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. - 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
- 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.
- 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 Processor → CPU Wait Time per Dispatch: latência de despacho por vCPU.
- Hyper‑V Hypervisor Logical Processor → Total 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 carga | Recomendação de topologia | Justificativa |
---|---|---|
Banco de dados com licenciamento por vCore | Sem 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 SMT | Algumas cargas ganham com SMT; outras sofrem por contendas de recursos internos. |
Workloads sensíveis a latência | Sem SMT na VM | Reduz preempções e partilha do núcleo físico com sibling. |
Servidores mistos e pouco CPU‑bound | Herdar 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
- Antes: meça no host e na VM cenários comparáveis (por exemplo, teste de um único thread e teste de 4 vCPU).
- Aplique: defina
HwThreadCountPerCore 1
na VM alvo e faça desligamento e novo início. - 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).
- 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étrica | Antes | Depois | Observação |
---|---|---|---|
Benchmark de um núcleo | ~120 | ~200 | Recupera 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 Dispatch | 50–80 µs (picos) | Menores e menos frequentes | Mais estabilidade de latência sob carga. |
Roteiro de decisão
Sintoma | Provável causa | Ação sugerida | Risco |
---|---|---|---|
VM com metade do desempenho do host com 4 vCPU | Topologia herdada como 2C/4T | Definir HwThreadCountPerCore 1 e reiniciar a frio | Menor aproveitamento de SMT para apps que o utilizam bem |
Picos de 60–80 µs de Wait Time | Limiares conservadores de alerta | Analisar tendência; otimizar plano de energia e SMT por VM | Ignorar tendências sustentadas pode ocultar contenção real |
Queda após migração ao vivo | Topologia efetiva não refeita | Desligar e ligar a VM | Janela curta de indisponibilidade |
Licenciamento por vCore desalinhado | SMT exposto sem ganho proporcional | Usar núcleos puros por VM crítica | Possí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.