Hyper‑V e Windows Server 2022: come recuperare le prestazioni CPU delle VM (core scheduler, SMT e HwThreadCountPerCore)

Le VM Hyper‑V su Windows Server 2022 possono sembrare “lente” dopo un upgrade dell’hardware. In molti casi non è un bug: è la conseguenza della combinazione tra core scheduler e Hyper‑Threading. Ecco come riconoscerlo, misurarlo e risolverlo con azioni concrete.

Indice

Scenario e sintomi

Un ambiente è stato aggiornato da Windows Server 2016 a Windows Server 2022 e migrato su host nuovi con CPU Intel Xeon Gold di 4ª generazione. Dopo la migrazione, alcune VM mostrano una perdita di prestazioni marcata nei benchmark (Cinebench) e nei carichi reali CPU‑bound: fino a ~80% più lente rispetto all’host fisico e decisamente sotto le attese rispetto all’upgrade hardware.

Gli allarmi del monitoraggio evidenziano CPU wait for dispatch e tempi di attesa/ready elevati, nonostante un basso livello di over‑commit complessivo. Inoltre, nei guest Windows Server 2016 compare ancora la stringa “10.0.14393” per i componenti di integrazione, sollevando dubbi su possibili driver obsoleti.

Il cuore del problema: SMT esposto dal core scheduler

A partire da Windows Server 2019, Hyper‑V adotta per impostazione predefinita il core scheduler, progettato per migliorare isolamento e sicurezza dei carichi multi‑tenant. Se l’host ha SMT (Hyper‑Threading) = 2, il core scheduler tende a mappare i vCPU in thread “fratelli” sullo stesso core, esponendo ai guest una topologia 2‑thread per core.

Topologia vista dal guest (configurazione predefinita con SMT=2)
VM con 4 vCPU  →  2 core × 2 thread (2c/4t)
VM con 8 vCPU  →  4 core × 2 thread (4c/8t)

Questo comporta due effetti pratici:

  1. Prestazioni per core “percepite” più basse in carichi CPU‑bound che scalano meglio su core pieni che su thread SMT. La VM con 4 vCPU “2c/4t” può risultare più lenta della stessa VM “4c/4t”.
  2. Licensing per core: in scenari in cui si licenzia “per core” nel guest (es. SQL Server), l’efficienza per licenza può ridursi perché due thread SMT non equivalgono a due core fisici in termini di throughput.

Perché crescono “CPU wait for dispatch” e i tempi di ready

Con il core scheduler attivo e SMT esposto, Hyper‑V può assegnare a un vCPU un solo thread del core fisico. Il thread gemello resta inutilizzato o assegnato ad altri vCPU con vincoli di co‑schedulazione. Se il carico nel guest richiede core pieni (e non beneficia di SMT), il risultato è un aumento dei tempi di attesa per l’accesso a core effettivi, che si manifesta come CPU Wait for Dispatch anche in assenza di over‑commit severo.

Falsi sospetti: Integration Services “vecchi”

Da Windows Server 2016 in poi, i Servizi di integrazione Hyper‑V sono incorporati nel sistema operativo e si aggiornano tramite Windows Update. La stringa di versione visualizzata nel registro (ad esempio 10.0.14393 per guest 2016) è normale e non richiede ISO o dischi d’installazione manuali. Gli scarti prestazionali di cui sopra non dipendono dai componenti di integrazione.

Verifiche rapide: cosa controllare subito

  1. SMT attivo sull’host
    Get-CimInstance -ClassName Win32_Processor | Select-Object Name, NumberOfCores, NumberOfLogicalProcessors Se NumberOfLogicalProcessors = 2 × NumberOfCores l’Hyper‑Threading è attivo.
  2. Scheduler Hyper‑V
    In Windows Server 2019/2022 il core scheduler è predefinito. Se in passato hai personalizzato il tipo di scheduler, verificane lo stato con bcdedit /enum {current} cercando la voce hypervisorschedulertype.
  3. Versione di configurazione VM
    Get-VM | Format-Table Name, Version Per poter controllare i thread per core nel guest è richiesta VM version ≥ 9.0. Se inferiore: # Necessita VM spenta. Operazione non reversibile. Update-VMVersion -Name "<NomeVM>"
  4. Thread per core esposti al guest
    Get-VMProcessor -VMName "<NomeVM>" | Format-List Count, HwThreadCountPerCore
    • HwThreadCountPerCore = 0: segue l’host (con SMT=2 → guest vede 2 thread per core).
    • HwThreadCountPerCore = 1: il guest vede 1 thread per core (topologia “4c/4t” con 4 vCPU).
  5. Piano energetico su host e guest
    powercfg /L powercfg /S SCHEME_MIN # "Prestazioni elevate"
  6. Contatori di performance (PerfMon o VM Insights)
    • Hyper‑V Hypervisor Virtual ProcessorCPU Wait Time Per Dispatch, % Guest Run Time, % Total Run Time.
    • Hyper‑V Hypervisor Logical Processor% Total Run Time, % Guest Run Time, % Hypervisor Run Time.
    • Correla i picchi di Wait for Dispatch con l’attività delle VM più rumorose.

Conseguenze sui benchmark e su carichi reali

Benchmark come Cinebench accentuano la differenza tra thread SMT e core pieni. In topologie “2c/4t” il punteggio multi‑core può restare ben al di sotto dell’host fisico e talvolta anche di configurazioni “4c/4t” con meno vCPU ma core “pieni”. In carichi reali (es. query OLTP CPU‑bound o engine .NET con alto parallelismo) la sensazione è di “CPU sempre al 50–60% ma richieste lente”: i thread SMT tengono occupati i vCPU senza restituire il throughput atteso.

Soluzioni pratiche e percorso decisionale

La buona notizia: non c’è un bug di Windows Server 2022. La perdita è architetturale e configurabile. Le opzioni seguenti sono ordinate dalla meno invasiva alla più drastica.

ObiettivoAzione consigliataNote
Far vedere al guest 4 core reali (4c/4t) anziché 2c/4tIn PowerShell sul nodo Hyper‑V:
Set-VMProcessor -VMName "<NomeVM>" -HwThreadCountPerCore 1
Forza 1 thread per core al guest. Disponibile con VM version ≥ 9.0. Riavvio VM consigliato.
Verificare/aggiornare la versione di configurazione VMGet-VM | ft Name, Version Update-VMVersion -Name "<NomeVM>" # VM spentaNecessario per gestire HwThreadCountPerCore. Operazione non reversibile; verifica compatibilità dei cluster.
Ripristinare prestazioni “equivalenti” al vecchio hostImposta HwThreadCountPerCore 1 oppure raddoppia i vCPU (es. 4→8) mantenendo SMT esposto.Dopo la modifica, ripeti i benchmark: tipicamente il divario scende a pochi punti percentuali rispetto al bare‑metal.
Uniformità di latenza su carichi sensibiliValuta il classic scheduler:
bcdedit /set hypervisorschedulertype Classic Restart-Computer
Può migliorare la latenza in ambienti non multi‑tenant. Riduce però l’isolamento di sicurezza garantito dal core scheduler.
Eliminare del tutto l’effetto SMTDisabilita Hyper‑Threading nel BIOS degli host.Soluzione drastica: riduce il parallelismo disponibile a tutte le VM ma semplifica licenze “per core” e prevedibilità.

Procedura consigliata passo‑passo

  1. Pianifica una finestra di manutenzione per le VM critiche. Esegui snapshot/checkpoint o assicurati di avere backup recenti.
  2. Allinea la versione delle VM: spegni le VM con versione < 9.0 e lancia Update-VMVersion. Verifica la compatibilità con i nodi del cluster.
  3. Imposta i thread per core: per le VM CPU‑bound o licenziate “per core”, esegui Set-VMProcessor -HwThreadCountPerCore 1. Riavvia la VM.
  4. Riesegui i benchmark (Cinebench, workload sintetici interni) e confronta con l’host fisico. Se necessario, raddoppia i vCPU mantenendo -HwThreadCountPerCore 1 per massimizzare la resa per core.
  5. Ottimizza il piano energetico su host e guest a “Prestazioni elevate” e verifica che il frequency scaling non limiti le frequenze turbo.
  6. Monitora con PerfMon/VM Insights: punta a CPU Wait for Dispatch stabile e riduci i vCPU se i ready/wait superano il 10–15% in idle.
  7. Documenta la topologia finale dei guest (es. “8 vCPU → 8c/8t” o “4 vCPU → 4c/4t”) per allineare team Ops e team Licensing.

Buone pratiche complementari

  • vNUMA: se una VM supera la capienza di un singolo NUMA node (per vCPU o per RAM), assicurati che la topologia vNUMA sia coerente con l’hardware per evitare cross‑node penalty.
  • Storage NVMe/SSD e queue depth adeguata: i test CPU‑bound possono diventare I/O‑bound in fretta; mantieni la latenza bassa per non “sprecare” cicli CPU in attesa.
  • Driver, UEFI/BIOS e micro‑code sempre aggiornati: mitigazioni di sicurezza e micro‑ottimizzazioni firmware impattano scheduling e boost.
  • Consolidamento ragionato: evita di concentrare troppi vCPU “caldi” sullo stesso socket/NUMA; distribuisci i carichi rumorosi.
  • Affinità CPU (solo quando necessario): Hyper‑V consente hard‑affinity per casi speciali; usala con parsimonia, preferendo il tuning di topologia.

Domande frequenti

Serve aggiornare manualmente i Servizi di integrazione nei guest?

No. Da Windows Server 2016 sono in‑box e si aggiornano via Windows Update. La stringa “10.0.14393” nei guest 2016 è normale.

Posso impostare HwThreadCountPerCore senza downtime?

La modifica è supportata su VM version ≥ 9.0. Pianifica comunque un riavvio del guest per garantire che il sistema operativo rilevi la nuova topologia CPU in modo pulito.

Meglio forzare 1 thread per core o disabilitare l’HT sul server?

Forzare HwThreadCountPerCore = 1 è più flessibile: puoi applicarlo solo alle VM sensibili o licenziate “per core”. Disabilitare HT nel BIOS impatta tutte le VM e riduce l’headroom complessivo dell’host.

Il classic scheduler è più veloce?

Dipende. In ambienti non multi‑tenant e latenza‑sensibili può offrire un profilo di prestazioni più prevedibile. In ambienti condivisi, il core scheduler resta preferibile per ragioni di isolamento e mitigazione di vulnerabilità basate su SMT.

Come interpreto “CPU Wait for Dispatch”?

È il tempo che un vCPU attende prima di essere eseguito su un processore logico. Valori elevati e stabili suggeriscono contention o topologia inefficiente (es. troppi vCPU mappati come thread SMT). Riduci i vCPU, forza 1 thread per core o ridistribuisci il carico per abbassarlo.

Esempi pratici: prima/dopo

ScenarioTopologia (guest)InterventoEsito atteso
VM SQL con 4 vCPU2c/4t (predefinito con SMT)HwThreadCountPerCore = 1Throughput per core ↑, latenza più stabile; licensing “per core” più efficiente.
VM app con 8 vCPU4c/8t (predefinito con SMT)Resta SMT esposto ma raddoppia vCPU se serve throughputMulti‑thread throughput ↑, senza toccare scheduler; consumo host ↑.
Farm web multi‑tenantMistoCore scheduler, HwThreadCountPerCore selettivoBuon compromesso tra sicurezza, prevedibilità e densità.

Checklist operativa

  • [ ] Verifica SMT sui nodi e piano energetico “Prestazioni elevate”.
  • [ ] Aggrega metriche: CPU Wait for Dispatch, % Guest Run Time, latenza app.
  • [ ] Aggiorna VM a versioni ≥ 9.0 (downtime pianificato).
  • [ ] Applica -HwThreadCountPerCore 1 alle VM CPU‑bound o licenziate “per core”.
  • [ ] Ricalibra i vCPU (riduci se idle ad alto ready; aumenta solo se necessario).
  • [ ] Riesegui benchmark e valida con carichi reali.
  • [ ] Documenta topologie e motivazioni per auditing e compliance.

Appendice: comandi utili (copiabili)

# 1) Stato SMT sull'host
Get-CimInstance -ClassName Win32_Processor | 
  Select-Object Name,NumberOfCores,NumberOfLogicalProcessors

2) Elenco VM e versione di configurazione

Get-VM | Format-Table Name, Version

3) Aggiornare versione VM (richiede VM spenta; non reversibile)

Update-VMVersion -Name ""

4) Forzare 1 thread per core nel guest

Set-VMProcessor -VMName "" -HwThreadCountPerCore 1
Restart-VM -Name ""

5) Verificare la topologia esposta

Get-VMProcessor -VMName "" |
Format-List Count, HwThreadCountPerCore, CompatibilityForMigrationEnabled

6) (Opzionale) Impostare classic scheduler a livello host

bcdedit /set hypervisorschedulertype Classic
Restart-Computer

7) Piano energetico ad alte prestazioni (host/guest)

powercfg /L
powercfg /S SCHEME_MIN 

Riepilogo per decisori

  • Non è un bug di Windows Server 2022: è l’effetto del core scheduler che espone SMT ai guest.
  • Obiettivo: performance per core e prevedibilità → forzare HwThreadCountPerCore = 1 sulle VM sensibili.
  • Obiettivo: throughput massimo assoluto → mantenere SMT, aumentare vCPU dove utile e monitorare contention.
  • Licensing “per core” → evitare di “pagare thread” con resa inferiore: privilegia core pieni nel guest.

Riferimenti (senza link)

  • Manage Hyper‑V Hypervisor Scheduler Types — documentazione Microsoft Learn (core vs classic scheduler, SMT e mapping dei thread).
  • Manage Hyper‑V Integration Services — documentazione Microsoft Learn (servizi di integrazione in‑box nei sistemi operativi moderni).
  • Core scheduler: does it make sense not to use hyper‑threading in this scenario? — discussione tecnica su Microsoft Q&A (considerazioni prestazionali e di licenza).

Conclusione

Il salto a Windows Server 2022 e a CPU moderne mette in evidenza un aspetto spesso trascurato: la topologia CPU che il guest vede. Con il core scheduler e SMT attivo, una VM con 4 vCPU può diventare “2c/4t”, penalizzando carichi che rendono meglio su core pieni e alterando la convenienza delle licenze per core. La correzione è semplice e a basso rischio: imposta HwThreadCountPerCore = 1 per le VM critiche (o disabilita l’HT a livello host se vuoi uniformità assoluta). Così le VM tornano a vedere lo stesso numero di core reali che avevano sul cluster 2016 e recuperano quasi tutto il vantaggio dell’hardware nuovo, con benefici tangibili in tempi di risposta, throughput e prevedibilità operativa.


Indice