Condividi tramite


Utilizzo elevato della CPU o della memoria e cicli di attesa di spin-wait in .NET Framework nelle macchine virtuali tramite processori Intel Skylake

Questo articolo illustra come risolvere il problema in cui si verifica un utilizzo elevato della CPU o della memoria nelle applicazioni Microsoft .NET Framework in macchine virtuali di Azure basate su processori Intel Skylake.

Versione originale del prodotto: .NET Framework
Numero KB originale: 4527212

Sintomi

Si riscontra un utilizzo di CPU o memoria superiore al previsto nelle macchine virtuali di Azure distribuite di recente nei computer basati sui processori Intel Skylake. In base a Intel, questa modifica influisce sulle prestazioni delle macchine virtuali e sull'esecuzione complessiva del carico di lavoro o dell'applicazione.

Il problema è causato da un aumento del ritardo delle istruzioni di sospensione per i processori Intel Skylake. È possibile notare questo problema in particolare nelle applicazioni .NET Framework. Ciò è dovuto al fatto che la modifica pausa latenza influisce sui cicli di attesa di rotazione lunghi comuni in .NET Framework.

Motivo

Nella microarchitectura skylake più recente, Intel ha aumentato il valore di latenza pausa fino a 140 cicli. Nella microarchitectura di prima generazione, il valore pausa latenza è di circa 10 cicli. Secondo Intel, questa modifica è stata apportata per migliorare la condivisione delle risorse. Per altre informazioni sulla modifica e sui relativi effetti, vedere la sezione 2.6.4 (Pause Latency in Skylake Client Microarchitecture) del seguente documento intel PDF: Intel 64 and IA-32 Architectures Optimization Reference Manual( Manuale di riferimento sull'ottimizzazione delle architetture di Intel 64 e IA-32).

Risoluzione

Importante

Seguire attentamente i passaggi in questa sezione. Se le modifiche al Registro di sistema vengono apportate in modo non corretto, possono verificarsi problemi gravi. Prima di apportare le modifiche, eseguire il backup del Registro di sistema per il ripristino nel caso si verifichino dei problemi.

Correzione di questo problema

Per risolvere questo problema, installare .NET Framework ottobre 2018 Security and Quality RollUp.

Annotazioni

In .NET Framework 4.8 la correzione è abilitata per impostazione predefinita. In .NET Framework 4.6.x e 4.7.x la correzione è disabilitata per impostazione predefinita e può essere abilitata manualmente.

Per abilitare la correzione per il ritardo di sospensione nei processori Skylake, avviare l'editor del Registro di sistema e aggiungere la Thread_NormalizeSpinWait chiave come valore DWORD alla sottochiave seguente:

  • Posizione: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework
  • Nome valore: Thread_NormalizeSpinWait
  • Valore (dati): 1

Annotazioni

Anche altre applicazioni dei clienti possono essere interessate dalla configurazione del timer, anche se questa impostazione non è abilitata per impostazione predefinita in alcuna versione di .NET Framework. Se le prestazioni del carico di lavoro sono ancora interessate dopo la modifica della latenza di sospensione, valutare se i timer sono un'origine significativa di conflitti di blocco. Se si determina che è true, passare alla sezione Correzione per i timer.

Correzione per i timer

Per abilitare manualmente la correzione, aggiungere la Switch.System.Threading.UseNetCoreTimer chiave come valore String alla sottochiave seguente:

  • Posizione: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AppContext
  • Nome valore: Switch.System.Threading.UseNetCoreTimer
  • Dati valore: true

Per altre informazioni sui timer, vedere la sezione AppContext per i consumer di libreria in Classe AppContext.

Domande frequenti

  • Questa modifica causa danni se è abilitato anche UseNetCoreTimer in tutti i tipi di hardware?

    La correzione timer non è attualmente abilitata per impostazione predefinita in alcuna versione di .NET Framework. Non è consigliabile modificare l'impostazione predefinita a livello locale.

  • Esistono altri problemi noti causati dalla modifica della latenza di sospensione in Skylake?

    La nuova misurazione di pausa latenza consuma anche tempo cpu aggiuntivo durante l'avvio. In genere, il valore è di circa 10 ms di tempo cpu. L'aumento della durata è considerato necessario per ottenere misurazioni più affidabili e migliorare la possibilità di risolvere il problema. Tuttavia, le applicazioni .NET Framework possono anche essere strumenti a esecuzione breve. L'uso frequente di tali strumenti può causare un utilizzo maggiore della CPU rispetto a prima dell'applicazione della correzione. Questo è stato considerato un compromesso accettabile per risolvere un problema più ampio e abilitare la correzione per impostazione predefinita in .NET Framework 4.8.

  • La correzione della latenza di sospensione di Skylake garantisce di risolvere il problema?

    No, la correzione non è garantita. Potrebbero esserci altri elementi non correlati al di fuori di questo problema che influiscono sulle prestazioni specifiche del carico di lavoro. L'efficacia della correzione è controllata sulla qualità della misurazione. Esistono limiti in uso per assicurarsi che i conteggi di spin a scalabilità eccessiva in .NET Framework non vengano superati. Tuttavia, le misurazioni non valida possono verificarsi quando la macchina virtuale viene caricata pesantemente. Ciò può impedire che la correzione sia effettiva. Nel peggiore dei casi (escluso il compromesso menzionato in A2), questa situazione sarebbe simile alla correzione non applicata.

  • Sono disponibili indicazioni per i tecnici del supporto tecnico su come è possibile rilevare che qualsiasi problema di prestazioni percepito è causato da questa modifica?

    È possibile determinare questo problema profilando l'applicazione usata. Il confronto dei profili con carichi simili tra una macchina virtuale basata su Skylake e una macchina virtuale basata su Skylake può mostrare molto più tempo relativamente impiegato nella clr!AwareLock::Contention macchina virtuale Skylake. Ciò indica che la correzione del ritardo di sospensione sarebbe utile se la macchina virtuale viene eseguita in un processore Skylake.

Per la correzione del timer, lo stack di chiamate mostrerà che clr!AwareLock::Contention viene chiamato da mscorlib.ni!System.Threading.TimerQueueTimer.Fire(). Se il Fire() metodo o altri metodi in TimerQueueTimer sono l'origine principale della contesa, ciò indicherà che la correzione del timer sarebbe utile.

È anche possibile monitorare i conflitti di blocco usando Monitor prestazioni. Per altre informazioni, vedere la sezione Frequenza di contesa/sec e Numero totale di voci di conflitti per blocchi CLR .NETAndThreads nella sezione Contatori delle prestazioni di blocco e thread in Contatori delle prestazioni in .NET Framework.

Clausola di esclusione della responsabilità per informazioni di terze parti

I prodotti di terze parti illustrati in questo articolo sono prodotti da aziende indipendenti da Microsoft. Microsoft non offre alcuna garanzia, implicita o espressa, sulle prestazioni o sull'affidabilità di questi prodotti.