WPR/WPA in pratica — Introduzione all'indagine delle prestazioni a livello di sistema per «tutto il PC è lento»

· · Windows, Prestazioni, WPR, WPA, ETW, Indagine sulle prestazioni, Risoluzione dei problemi, Sviluppo Windows

«Hanno detto che tutto il PC è diventato lento dopo aver installato una nuova app. Ma quando guardo il Task Manager, sia CPU sia memoria hanno margine.» «C’è un PC che impiega 3 minuti ad avviarsi. Non ho idea di cosa non vada.» — Le consulenze sulle prestazioni arrivano davvero spesso in questa forma. Ciò che hanno in comune è che guardare un processo specifico non dà una risposta.

Gli strumenti a livello di processo ci sono. Accesso a file e registro si vede con Process Monitor, e la CPU e il GC di un’app .NET si possono seguire con PerfView. Ma un sintomo come «tutto il PC è lento» o «la CPU è inattiva ed è comunque lento» parte dal non sapere nemmeno quale processo sia il colpevole. L’app A può essere lenta per una scansione antivirus, o perché un altro servizio sta scrivendo pesantemente su disco, o per una catena di lock che attraversa più processi. Ciò che vi serve è un dato che ha registrato non l’interno di un processo ma l’OS nel suo insieme su una sola linea temporale.

Gli strumenti per catturare e leggere questo sono Windows Performance Recorder (WPR) e Windows Performance Analyzer (WPA). WPR registra l’attività a livello di OS su base ETW (Event Tracing for Windows), e WPA analizza quella registrazione in grafici e tabelle. Chi ha usato la CPU su quale stack, chi un thread stava aspettando, quale processo ha emesso I/O disco verso quale file — fatti uno o due gradini sotto il Task Manager restano tutti, con timestamp.

Rivolto al personale IT delle piccole e medie imprese e agli sviluppatori di app Windows, questo articolo organizza la pratica della cattura con WPR e come leggere WPA — in particolare la differenza tra indagare «quando la CPU è alta» e «quando la CPU è bassa ed è comunque lento» — a partire dalle fonti primarie ad agosto 2026.

1. Prima di tutto, la conclusione

  • La prima scelta per un’indagine «tutto il PC è lento» è WPR/WPA, che cattura e legge una traccia ETW a livello di OS. I problemi che gli strumenti a livello di processo (Task Manager, Procmon, PerfView) non riescono a inchiodare si possono seguire se guardate ogni processo e il kernel su una sola linea temporale.12
  • Lo strumento di cattura wpr.exe è incluso in Windows 8.1 e successivi. Potete usarlo senza installazioni extra. L’edizione GUI (WPRUI) e lo strumento di analisi WPA sono inclusi nel Windows ADK.12
  • La procedura di base è tre righe. Come amministratore, wpr -start GeneralProfile -filemode → riproducete il problema → wpr -stop C:\temp\trace.etl. Ricordate solo questo e potete iniziare a catturare.3
  • La baseline sul campo è una divisione «nell’ambiente del cliente, solo cattura con wpr.exe; la lettura è WPA sulla vostra macchina». Potete catturare anche su un server in cui non potete installare software. È la stessa idea della cattura di pacchetti: «cattura con uno strumento standard, leggi in Wireshark».1
  • Leggere WPA inizia classificando «CPU, attesa o I/O». Se la CPU brucia, CPU Usage (Sampled); se la CPU è inattiva ed è comunque lento, analisi delle attese in CPU Usage (Precise); se si sospetta il disco, Disk Usage — il percorso si spezza all’inizio.45
  • CPU Usage (Sampled) mostra «quale funzione ha usato la CPU» da un campionamento circa ogni 1 millisecondo. Potete percorrere la scomposizione del «50%» del Task Manager da processo → thread → stack → funzione.6
  • CPU Usage (Precise) è un record completo dei context switch, e vi dice «chi un thread stava aspettando». Percorrere Waits (tempo di attesa), ReadyingProcess (chi lo ha svegliato) e ReadyThreadStack (lo stack di chi ha svegliato) è la tecnica che questo articolo vuole di più trasmettere.47
  • Leggere uno stack richiede la configurazione dei simboli. WPA fa riferimento al server pubblico dei simboli Microsoft per default. Per vedere i nomi di funzione nella vostra app, aggiungete il percorso dei vostri PDB.8
  • Un file ETL contiene informazioni interne del sistema come nomi di processo e percorsi di file. Tenete la cattura al minimo necessario, e decidete come verrà trattata se esce dall’azienda prima di catturare.

2. Dove stanno gli strumenti — WPR cattura, WPA legge

Windows Performance Toolkit (WPT) è il set di strumenti di indagine sulle prestazioni incluso nel Windows ADK (Windows Assessment and Deployment Kit); il centro è la coppia di WPR e WPA.2 I ruoli sono nettamente spezzati.

  • WPR (Windows Performance Recorder) = cattura. Raggruppa gruppi di provider ETW in un’unità chiamata «profilo», avvia e ferma la registrazione e produce un file ETL. L’edizione da riga di comando, wpr.exe, è inclusa in Windows 8.1 e successivi, senza installazioni extra. L’edizione GUI (WPRUI.exe) è inclusa nell’ADK.1
  • WPA (Windows Performance Analyzer) = analisi. Apre un file ETL e lo analizza in grafici e tabelle. È richiesta un’installazione ADK.2

In altre parole, non c’è niente che dobbiate piazzare nell’ambiente del cliente. Catturate con il wpr.exe standard dell’OS, portate a casa il file ETL e leggetelo in WPA sul vostro PC — vale la stessa divisione della cattura di pacchetti: «cattura con pktmon, leggi in Wireshark».

La divisione tra catturare con WPR e leggere con WPANell'ambiente del cliente, registrate con il wpr.exe standard dell'OS e produce un file ETL; portatelo a casa e analizzatelo in WPA installato via ADK sul vostro PCIl vostro PC(WPA via ADK)PC del cliente(nessuna installazione extra)Portare a casaAnalizzare grafici e tabelleFile ETLwpr start → riproduci → stop

Figura 1: Nell’ambiente del cliente, registrate con il wpr.exe standard dell’OS e produce un file ETL; portatelo a casa e analizzatelo in WPA installato via ADK sul vostro PC.

Come differisce da strumenti simili vale la pena organizzarlo prima.

  Process Monitor PerfView WPR + WPA
La domanda a cui risponde Quale processo ha fatto cosa a quale percorso, e cosa è successo Come stanno CPU, GC e allocazione di un’app .NET Attraverso l’OS, dove è sparito il tempo
Ambito Log di operazioni su file, registro e avvio processi Prima il codice gestito CPU, attese, disco, I/O file, alimentazione e simili a livello di sistema
Sintomi adatti Una impostazione non viene letta, ACCESS DENIED Lentezza o memoria della vostra app .NET da sola Tutto il PC è lento, la CPU è inattiva ed è comunque lento, processo colpevole sconosciuto
Articolo Guida pratica a Procmon Introduzione pratica a PerfView Questo articolo

Se Procmon è un log di operazioni di «cosa ha fatto» e PerfView è «cosa è successo dentro .NET», WPA è uno strumento che audita «dove è sparito il tempo» attraverso ogni processo. I meccanismi di ETW stesso, e come strumentare la vostra app con ETW, sono trattati in «Introduzione al registro eventi di Windows e a ETW». Se la vostra app emette eventi ETW, i checkpoint della vostra app sono registrati nella stessa traccia e allinearli diventa molto più facile. WPR, però, registra solo eventi dai provider abilitati dal profilo di registrazione che avete scelto. GeneralProfile non include i vostri provider, quindi se volete mescolarli, preparate un profilo di registrazione personalizzato (.wprp) che abilita i vostri provider e combinate come wpr -start GeneralProfile -start MyApp.wprp!MyAppProfile, specificando il nome del profilo dentro il file .wprp con !3.

3. Cattura in pratica (WPR) — start, riproduci, stop

La procedura di base in un terminale amministratore.

:: List of built-in profiles you can use
wpr -profiles

:: 1. Start capture (general-purpose profile, file mode)
wpr -start GeneralProfile -filemode

:: 2. Reproduce the issue (check capture status with wpr -status)

:: 3. Stop and save (you can attach a description of the problem).
::    Create the destination folder in advance (without it, -stop fails to save)
mkdir C:\temp 2>nul
wpr -stop C:\temp\slow-pc.etl "Reproduced the issue where the whole PC becomes slow while starting App X"

:: To abandon without saving
wpr -cancel

Ciò che passate a -start è un profilo, un fascio dei provider ETW di cui l’indagine ha bisogno.3 Ricordare solo quelli che usate spesso è sufficiente.9

Profilo Cosa registra Quando usarlo
GeneralProfile Un set generico che include campioni CPU, context switch e I/O disco Partite da qui. La prima mossa quando non sapete cosa non va
CPU Utilizzo CPU dettagliato Quando sapete già che la CPU sta bruciando
DiskIO Attività I/O disco Quando si sospetta il disco
FileIO Attività I/O file Quando volete seguire quale file viene acceduto

Potete specificare più profili insieme allineando -start (per esempio wpr -start GeneralProfile -start FileIO -filemode).3

Flusso di cattura WPR e come scegliere una modalitàUn problema che potete riprodurre sul posto si cattura breve e affidabile in file mode; un problema di cui non conoscete i tempi si aspetta nel ring buffer di default in memory mode. Un problema durante avvio o logon usa una boot trace. In ogni caso la procedura start / riproduci / stop è la stessaSul postoTempi sconosciutiAvvio o logonQuando si verifica?File mode: cattura breveMemory mode: aspetta(3.1)Boot trace(cap. 8)start → riproduci → stop

Figura 2: Un problema che potete riprodurre sul posto si cattura breve e affidabile in file mode; un problema di cui non conoscete i tempi si aspetta nel ring buffer di default in memory mode. Un problema durante avvio o logon usa una boot trace. In ogni caso la procedura start / riproduci / stop è la stessa.

3.1. Memory mode e File mode — potete riprodurre, o aspettate

WPR ha due modalità di destinazione della registrazione; il default è Memory mode (un buffer circolare in memoria). È un ring buffer che sovrascrive dagli eventi più vecchi, quindi è adatto a lasciare la cattura in esecuzione mentre aspettate un problema di cui non conoscete i tempi, e fermarla quando succede. Aggiungere -filemode passa a File mode, e tutto viene registrato in un file continuo. Questo non viene sovrascritto; l’unico tetto è lo spazio disco libero, e il file cresce senza limiti.10

Come Memory mode e File mode registranoMemory mode registra su un buffer circolare in memoria; gli eventi più vecchi vengono sovrascritti e restano solo i più recenti, quindi è adatto ad aspettare. File mode tiene tutto in un file, ma l'unico tetto è lo spazio disco libero, quindi è adatto a una riproduzione breve e affidabileEventi ETWMemory mode: ring bufferFile mode: far crescere un fileAspettare tempi sconosciutiRiproduzione breve e affidabile

Figura 3: Memory mode registra su un buffer circolare in memoria; gli eventi più vecchi vengono sovrascritti e restano solo i più recenti, quindi è adatto ad aspettare. File mode tiene tutto in un file, ma l’unico tetto è lo spazio disco libero, quindi è adatto a una riproduzione breve e affidabile.

Una regola empirica per scegliere è la seguente.

  • Riproducibile sul posto → File mode. Partite subito prima della riproduzione, fermatevi subito dopo e tenete la cattura entro pochi minuti
  • Tempi sconosciuti → Aspettate in Memory mode (il default). Appena si verifica, wpr -stop
  • Anche pochi minuti di GeneralProfile possono produrre un ETL nella classe delle centinaia di MB fino ai GB. Un file troppo grande può diventare inanalizzabile in WPA, quindi «più a lungo catturate, meglio è» è controproducente1011

Per catturare dalla GUI, avviate WPRUI, scegliete un profilo e Logging mode, e Start/Save. L’How-to ufficiale riassume la procedura.11 Se chiedete a un contatto sul sito del cliente di catturare, i tre comandi sopra possono andare in una procedura così come sono.

4. Le basi di come leggere WPA — Grafici, la regola d’oro delle tabelle e restringere il tempo

Quando aprite un ETL catturato in WPA, il Graph Explorer a sinistra elenca miniature di grafici in categorie come System Activity, Computation, Storage e Memory.12 Trascinate un grafico che volete vedere sulla scheda Analysis a destra, e compare un grafico sopra e una tabella sotto. Le prime tre cose da interiorizzare sono queste.

  1. La regola d’oro delle tabelle — l’ordine delle colonne decide il raggruppamento. Una tabella WPA ha due barre verticali, oro e blu, e le colonne a sinistra della barra oro gerarchizzano (raggruppano) i dati in quell’ordine, e le colonne a destra della barra blu sono aggregati.13 Disponetele Processo → Stack e ottenete un’aggregazione di stack per processo; Stack → Processo e ottenete un’aggregazione di ogni processo che usa lo stesso stack — trascinare le colonne per riordinarle è di per sé un’operazione di analisi. Capito questo punto, ogni tabella WPA si legge allo stesso modo.
La regola d'oro delle tabelle — le due barre e il ruolo delle colonneLe colonne a sinistra della barra oro gerarchizzano i dati in quell'ordine; le colonne tra la barra oro e quella blu sono colonne di visualizzazione; le colonne a destra della barra blu sono aggregati. Trascinare le colonne per riordinarle è di per sé un'operazione di analisiA sinistra dell'oro: raggruppamentoBarra oroTra le barre: visualizzazioneBarra bluA destra del blu: aggregatiTrascinare le colonne per analizzare

Figura 4: Le colonne a sinistra della barra oro gerarchizzano i dati in quell’ordine; le colonne tra la barra oro e quella blu sono colonne di visualizzazione; le colonne a destra della barra blu sono aggregati. Trascinare le colonne per riordinarle è di per sé un’operazione di analisi.

  1. Restringete l’intervallo di tempo. Trascinate sul grafico per selezionare un intervallo, poi tasto destro e «Zoom», e l’aggregazione passa solo a quell’intervallo. L’indagine delle prestazioni è sempre, in principio, guardare solo «l’intervallo in cui il problema stava succedendo» (capitolo 9).
  2. Configurate i simboli. Per leggere uno stack per nome di funzione, eseguite Trace > Load Symbols dal menu.14 Per default fa riferimento al server pubblico dei simboli Microsoft (msdl.microsoft.com), quindi gli stack di Windows stesso si possono risolvere se avete una connessione Internet. Per vedere i nomi di funzione nella vostra app, aggiungete la cartella dei PDB della vostra app in Trace > Configure Symbol Paths.8 Che cosa è un PDB, e perché dovreste sempre tenerlo anche per una build Release, è riassunto in «Che cos’è un PDB (Program Database)?». Per le immagini native NGen di .NET Framework, WPR genera PDB NGen (.ngenpdb) al momento della cattura e li mette in una cartella accanto alla traccia, e WPA li consulta automaticamente.8 Questo è un meccanismo solo per le immagini NGen, e il codice JIT .NET ordinario della vostra app è fuori ambito. Il mapping da un indirizzo di codice JIT a un nome di funzione si risolve dagli eventi JIT che emette il CLR, quindi quando indagate un’app .NET, preparate un profilo di registrazione (.wprp) che abilita i provider CLR (Microsoft-Windows-DotNETRuntime e il Rundown corrispondente) e combinate allo stesso modo dei vostri provider nel capitolo 3, wpr -start GeneralProfile -start MyDotNet.wprp!profile-name, così che gli eventi CLR siano inclusi nella traccia (potete controllare quali profili built-in offre il vostro WPR locale con wpr -profiles). Sopra a questo, tenete i PDB generati dalla build per il mapping alle righe di sorgente, e aggiungeteli al percorso dei simboli di cui sopra.
Risoluzione dei simboli per leggere uno stack per nome di funzioneEseguire Trace Load Symbols risolve Windows stesso dal server pubblico dei simboli Microsoft, e la vostra app dai PDB di build aggiunti al percorso dei simboli. Le immagini NGen usano i PDB NGen che WPR genera; il codice JIT .NET si risolve dagli eventi JIT del CLR nella traccia più i PDB di buildTrace > Load SymbolsWindows: simboli pubbliciVostra app: PDB di buildNGen: WPR .ngenpdbJIT: eventi CLR + PDB

Figura 5: Eseguire Trace Load Symbols risolve Windows stesso dal server pubblico dei simboli Microsoft, e la vostra app dai PDB di build aggiunti al percorso dei simboli. Le immagini NGen usano i PDB NGen che WPR genera; il codice JIT .NET si risolve dagli eventi JIT del CLR nella traccia più i PDB di build.

Una volta preparati, entrate dal ramo successivo. In quell’intervallo, la CPU era alta o bassa? Se alta, capitolo 5 (Sampled); se bassa e comunque lento, capitolo 6 (Precise).

Ramo per scegliere un grafico WPA dal sintomoZoomate sull'intervallo del problema; se la CPU è alta andate a CPU Usage Sampled; se è bassa e comunque lento, controllate un pin single-core / single-thread e poi l'analisi delle attese in CPU Usage Precise; se si sospetta il disco, Disk Usage e File IOAltaBassa, comunque lentoNoDisco sospettatoZoom sull'intervallo del problemaCPU in quell'intervallo?Cap. 5: SampledPin 1 core / 1 thread?Cap. 6: PreciseCap. 7: Disco / I/O file

Figura 6: Zoomate sull’intervallo del problema; se la CPU è alta andate a CPU Usage Sampled; se è bassa e comunque lento, controllate un pin single-core / single-thread e poi l’analisi delle attese in CPU Usage Precise; se si sospetta il disco, Disk Usage e File IO.

5. Quando la CPU è alta — «Chi sta bruciando quale funzione» con CPU Usage (Sampled)

Se la CPU è inchiodata, ciò che guardate è CPU Usage (Sampled). Sono dati di campionamento che hanno registrato, circa ogni 1 millisecondo su ogni CPU, «quale stack di quale processo sta girando ora», e il rapporto dei conteggi di campione è la scomposizione del tempo CPU così com’è.6

Come funziona CPU Usage SampledCirca ogni 1 millisecondo, lo stack in esecuzione su ogni CPU viene registrato, e il rapporto aggregato dei campioni è la scomposizione del tempo CPU. Leggete da processo a thread, stack e funzione. L'attività breve che finisce tra i campioni non compareInterrupt circa ogni 1 msRegistra lo stack in esecuzioneRapporto campioni = scomposizione CPUProcesso → Thread → StackL'attività tra i campioni viene persa

Figura 7: Circa ogni 1 millisecondo, lo stack in esecuzione su ogni CPU viene registrato, e il rapporto aggregato dei campioni è la scomposizione del tempo CPU. Leggete da processo a thread, stack e funzione. L’attività breve che finisce tra i campioni non compare.

  1. Da Computation del Graph Explorer, mettete CPU Usage (Sampled) sulla scheda Analysis e scegliete il preset Utilization by Process, Stack.5
  2. Guardate i processi in ordine decrescente di Weight (o Count). L’identità di ciò che era «50%» nel Task Manager diventa chiara prima a livello di processo.
  3. Espandete la colonna Stack del processo colpevole. Gli stack sono aggregati come albero, e percorrere il percorso in cui il numero non scende molto a un ramo vi fa atterrare sulla funzione che sta bruciando CPU. Se i simboli sono risolti, è una linea retta fino a quale funzione nel vostro codice.
  4. Se espandere l’albero è tedioso, passate la visualizzazione del grafico a Flame. È disegnato con larghezza = quota di tempo CPU, quindi quale percorso di chiamata domina è ovvio a colpo d’occhio. CPU Usage (Sampled) ha anche un preset Flame by Process, Stack.13

C’è una cautele. Poiché è campionamento, l’attività breve che finisce tra i campioni non compare.6 Ricordatelo come uno strumento per vedere «dove la CPU è stata usata in aggregato», non uno strumento per misurare la durata esatta per invocazione.

6. Quando la CPU è bassa ed è comunque lento — CPU Usage (Precise) e analisi delle attese

Questo è il cuore dell’articolo. Prima di procedere all’analisi delle attese, però, c’è una cosa da confermare. «L’utilizzo complessivo della CPU è basso» non significa «la CPU non è il collo di bottiglia». Su un PC a 16 core, un lavoro seriale inchiodato a un core (un singolo thread UI che gira a palla) sembra solo circa il 6% complessivo. Prima controllate nel Sampled del capitolo 5 (o Utilization by CPU di CPU Usage (Precise)) che non ci sia un pin su un core o un thread specifico, e se non c’è, venite a questo capitolo — il lavoro non è incapace di girare, sta aspettando. Ciò che vi dice cosa sta aspettando è CPU Usage (Precise).

Dove Sampled è campionamento, Precise è un record completo dei context switch (cambi di thread). Un thread entra in attesa, viene svegliato da qualcuno (Ready) e atterra su una CPU — quel viaggio di andata e ritorno resta una riga alla volta, e potete leggere le colonne seguenti.74

Colonna Significato
NewThreadStack Su quale stack quel thread è entrato in attesa (= cosa stava facendo quando si è fermato)
Waits (us) Quanto ha aspettato
Ready (us) Quanto è stato fatto aspettare dallo sveglio fino ad atterrare su una CPU (contesa CPU)
ReadyingProcess / ReadyingThreadId Il processo e il thread che hanno svegliato quel thread (rilasciato l’attesa)
ReadyThreadStack Su quale stack chi ha svegliato lo ha svegliato
Un viaggio di andata e ritorno di attesa e come corrispondono le colonneUn thread entra in attesa sullo stack che resta in NewThreadStack, e aspetta per il tempo Waits. Quando qualcuno lo sveglia, quella parte resta in ReadyingProcess e ReadyThreadStack; aspetta il tempo Ready per la contesa CPU e poi gira di nuovoEntra in attesaQualcuno lo svegliaAtterra su una CPUIn esecuzioneAttesa(Waits us)Ready(contesa CPU)Di nuovo in esecuzioneNewThreadStack / ReadyingProcess

Figura 8: Un thread entra in attesa sullo stack che resta in NewThreadStack, e aspetta per il tempo Waits. Quando qualcuno lo sveglia, quella parte resta in ReadyingProcess e ReadyThreadStack; aspetta il tempo Ready per la contesa CPU e poi gira di nuovo.

Il pattern di lettura è il seguente.4

  1. Applicate il preset Utilization by Process, Thread e aggiungete NewThreadStack e ReadyThreadStack alle colonne.
  2. Prima identificate il thread che stava eseguendo l’operazione ritardata (il thread UI, il thread che gestiva la richiesta in questione). Guardare solo in ordine decrescente di Waits totali è confuso, perché i thread che «stanno intenzionalmente aspettando tutto il tempo», come una message pump o un timer, occupano la cima. Una volta trovato il thread bersaglio, se il suo CPU Usage (ms) è grande è un problema CPU del capitolo 5; se dominano i Waits è un problema di attesa.
  3. Espandete NewThreadStack e vedete cosa stava facendo quando si è fermato. WaitForSingleObject o EnterCriticalSection è un’attesa di lock; dentro I/O sincrono come ReadFile è un’attesa I/O; dentro una ricezione socket è in attesa che il peer risponda.
  4. Poi vedete chi ha rilasciato l’attesa. Espandete ReadyThreadStack e controllate ReadyingProcess / ReadyingThreadId. Se è stato svegliato dal KiTimerExpiration del kernel era un timer (= ha dormito fino a un timeout); se è stato svegliato dalla gestione del completamento I/O, questo conferma che era un’attesa I/O.4
  5. Se la parte che lo ha svegliato è un altro thread o un altro processo, indagate quel thread con la stessa procedura. «A stava aspettando che B rilasciasse un lock, B stava aspettando la risposta RPC di C, C stava aspettando I/O disco» — ciò che avete quando avete percorso questa catena fino alla radice è il critical path del ritardo.7
La catena del critical path che percorrete nell'analisi delle atteseVedete nel NewThreadStack del thread ritardato A cosa stava facendo quando si è fermato, identificate chi ha svegliato B da ReadyThreadStack e ReadyingProcess, e indagate B con la stessa procedura fino all'I/O disco alla radiceAttesa di lockAttesa RPCAttesa I/O sincronoIl completamento sveglia CLa risposta sveglia BIl rilascio del lock sveglia AThread A(lavoro ritardato)Thread B(tiene il lock)Processo CI/O disco(radice)

Figura 9: Vedete nel NewThreadStack del thread ritardato A cosa stava facendo quando si è fermato, identificate chi ha svegliato B da ReadyThreadStack e ReadyingProcess, e indagate B con la stessa procedura fino all’I/O disco alla radice.

In un caso come «l’abbiamo multithreadato e non è diventato più veloce», questa procedura mostra ogni worker in fila su un singolo lock così com’è. Evitare la contesa sui lock per progetto è trattato in «Best practice pratiche sul multithreading: edizione .NET», e il meccanismo Windows che gira su una notifica di completamento invece di aspettare in I/O sincrono è trattato in «I/O Completion Ports (IOCP) e il thread pool .NET». Inchiodare «chi stava aspettando» in WPA e sistemarlo con quegli argomenti di progetto è un flusso continuo.

7. Disco e I/O file — Identificare «qualcuno sta scansionando il disco»

Un colpevole classico di «tutto il PC è lento» non è la CPU ma il disco. Indagate con Disk Usage e File I/O nella categoria Storage.15

Disk Usage è un record di I/O disco, e due colonne contano. Disk Service Time è il tempo che il dispositivo disco ha effettivamente speso per elaborare quell’I/O; IO Time è il tempo dall’ingresso dell’I/O nella coda OS fino al completamento. IO Time è sempre almeno Service Time per la quantità di accodamento, quindi se IO Time è molto più lungo di Service Time, quell’I/O stava «aspettando in coda».6 Questo da solo, però, non decide se il colpevole che ha fatto la coda è un altro processo, o solo l’I/O pesante di quel processo stesso in fila su un dispositivo lento. Non tirate la conclusione qui; sistematela con Service Time (la risposta propria del dispositivo) e la scomposizione successiva per processo, percorso e stack.

Poi, con il preset Utilization by Process, Path Name, Stack, guardate quale processo ha emesso I/O verso quale file da quale stack, in ordine decrescente di IO Time o Size.15 Le risposte che escono spesso sul campo sono queste due.

  • L’antivirus stava scansionando ogni file. Nella finestra in cui l’app era lenta ad avviarsi, il processo antivirus si vede emettere un grande volume di letture. Nome processo, percorso e volume sono evidenza così com’è per una discussione sulle esclusioni.
  • Un altro processo stava scrivendo pesantemente. Backup, l’indicizzatore, log scritti troppo, e simili. Quando una scrittura raggiunge il disco coinvolge il cache manager, quindi il fatto che «il momento in cui avete scritto» e «il momento in cui il disco è occupato» possono divergere è trattato anche in «Cache Manager — Quando il vostro WriteFile raggiunge davvero il disco?».

File I/O è uno strato sopra, un record delle operazioni sui file che l’app ha emesso (Create/Read/Write e simili), e preset come Duration by Process, Thread, Type possono aggregare il tempo per nome file e per operazione.15 Un caso che spende tempo nel file system o in un filter driver prima di raggiungere il disco non compare in Disk Usage, quindi la discordanza stessa — «Disk Usage è tranquillo ma File I/O è lento» — è un indizio. Se volete partire dai meccanismi di I/O sincrono e asincrono, vedete «I/O sincrono e asincrono — Cosa significa davvero OVERLAPPED».

I diversi strati che vedono File IO e Disk UsageUn'operazione file di un'app viaggia attraverso file system e filter driver dalla coda I/O dell'OS al dispositivo disco. File IO registra le operazioni allo strato superiore; Disk Usage registra l'I/O che ha raggiunto il disco; la differenza tra IO Time e Disk Service Time è il tempo di codaApp: ReadFile / WriteFileFS e filtri(File I/O)Coda I/O dell'OSDispositivo disco(Disk Usage)Perso da Disk UsageIO Time − Service TimeService Time = dispositivo

Figura 10: Un’operazione file di un’app viaggia attraverso file system e filter driver dalla coda I/O dell’OS al dispositivo disco. File IO registra le operazioni allo strato superiore; Disk Usage registra l’I/O che ha raggiunto il disco; la differenza tra IO Time e Disk Service Time è il tempo di coda.

La linea di pensiero «forse è a corto di memoria e sta facendo swapping» può avere un primo isolamento in Task Manager e Resource Monitor prima di andare a WPA. Non liquidatela però dalla sola memoria committed — anche con margine di commit, è possibile una situazione in cui la pressione sulla memoria fisica taglia il working set e i hard fault continuano. Controllate anche la memoria fisica disponibile e «Hard Faults/sec» di Resource Monitor. Come leggerli è in «Che cosa significa davvero l’«utilizzo della memoria» di Windows?».

8. Avvio e logon lenti — L’ingresso in una boot trace

Un tipo «impiega 3 minuti ad avviarsi» finisce prima che possiate eseguire a mano wpr -start. WPR ha una boot trace, e potete disporre che l’OS inizi a registrare automaticamente al prossimo avvio.3

:: 1. Arrange automatic recording on the next boot
wpr -boottrace -addboot GeneralProfile -filemode

:: 2. Restart (reproduce the slow boot)

:: 3. After boot, stop recording and save (the arrangement is also cleared)
mkdir C:\temp 2>nul
wpr -boottrace -stopboot C:\temp\boot.etl "Issue where boot takes 3 minutes"
Flusso della boot traceDopo aver disposto la registrazione automatica al prossimo avvio con addboot e riavviato, l'OS inizia a registrare automaticamente all'avvio. Salvare con stopboot dopo il logon cancella anche la disposizione. Per abbandonare, cancellatela con cancelbootwpr -boottrace -addbootRiavvio(avvio lento)L'OS registra all'avvioDopo il logon: -stopbootAbbandonare: -cancelboot

Figura 11: Dopo aver disposto la registrazione automatica al prossimo avvio con addboot e riavviato, l’OS inizia a registrare automaticamente all’avvio. Salvare con stopboot dopo il logon cancella anche la disposizione. Per abbandonare, cancellatela con cancelboot.

La misurazione di avvio e spegnimento che un tempo apparteneva a xbootmgr si può eseguire anche nel WPR attuale con opzioni come -onoffscenario Boot.3 Una traccia catturata si legge con lo stesso toolkit dei capitoli precedenti. Guardate quale processo è nato quando su una linea temporale nel grafico Processes, zoomate sulla finestra in cui l’avvio è bloccato, e classificate CPU, attesa o disco — un’app di avvio che aspetta qualcosa in serie, un avvio di servizio bloccato su un I/O specifico, e simili diventano visibili. L’analisi dell’avvio è una specialità profonda a sé, quindi questo articolo arriva solo all’ingresso: «un problema che non potete catturare a mano si può comunque catturare con WPR». Partite afferrando il quadro complessivo con una boot trace GeneralProfile.

9. Un pattern di lavoro — Classifica → Zoom → Stack, ripetuto

Ora che gli strumenti sono chiari, ecco il pattern per l’indagine nel suo insieme.

  1. Inchiodate l’ora del fenomeno. Non «era lento», ma «10:23:40–10:24:10 era lento». Log dell’app, il registro eventi, una nota di chi ha operato — qualsiasi cosa va bene. Se la vostra app scrive checkpoint su ETW o il registro eventi, gli eventi dentro la traccia diventano picchetti temporali così come sono.
  2. Zoomate solo su quell’intervallo. Un’aggregazione di tutta la traccia è mediata, e l’anomalia che conta viene diluita. L’analisi WPA è sempre un confronto tra «l’intervallo che era anomalo» e «l’intervallo che era normale».
  3. Classificate «CPU, attesa o I/O» per primi. Guardate CPU Usage (Sampled); se sta bruciando, capitolo 5. Se non sta bruciando, Waits in CPU Usage (Precise) (capitolo 6). Se Disk Usage IO Time è gonfio, capitolo 7. Prendere prima questa forchetta a tre vie vi tiene dal perdervi.
  4. Ripetete ipotesi → zoom → stack. Se pensate «antivirus?», restringete a quel processo e sostenetelo con lo stack. Se non regge, l’ipotesi successiva. Non tirare una conclusione prima di aver percorso fino allo stack e sostenuto è la disciplina di questo tipo di indagine.
Il ciclo iterativo di un'indagine sulle prestazioniInchiodate l'ora del fenomeno, zoomate sull'intervallo, classificate CPU / attesa / I/O, formate un'ipotesi e restringete, e sostenetela con lo stack. Se regge, la causa è confermata; se no, ripetete con l'ipotesi successivaReggeNon reggeInchiodare l'oraZoom su quell'intervalloClassificare CPU / attesa / I/OIpotesi e restringereSostenere con lo stackCausa confermata

Figura 12: Inchiodate l’ora del fenomeno, zoomate sull’intervallo, classificate CPU / attesa / I/O, formate un’ipotesi e restringete, e sostenetela con lo stack. Se regge, la causa è confermata; se no, ripetete con l’ipotesi successiva.

Infine, la gestione del file di cattura. Un file ETL riflette ampiamente l’interno del sistema: i nomi di ogni processo, i percorsi dei file aperti, i moduli caricati e (a seconda del profilo) i nomi delle chiavi di registro. Una cattura GeneralProfile standard non include corpi di dati come i contenuti delle comunicazioni, ma se avete abilitato un provider personalizzato, il payload di quell’evento (stringhe che l’app ha registrato, e simili) entra così com’è. Dopo aver confermato cosa emettono i provider che avete abilitato, trattatelo come un file abbastanza riservato da uscire dall’azienda. Come per la cattura di pacchetti, incorporate la cattura al minimo necessario, l’accordo con chi lo consegnate, e un periodo di conservazione e la cancellazione nella procedura.

Cosa riflette un file ETL, e come trattarloUn ETL riflette ogni nome di processo, i percorsi dei file aperti, i moduli e a seconda del profilo i nomi delle chiavi di registro; abilitare un provider personalizzato include anche il suo payload. Trattatelo come riservato: cattura al minimo necessario, accordo con l'altra parte, e un periodo di conservazione e cancellazioneFile ETLNomi, percorsi, moduliChiavi di registro(alcune)Payload personalizzatoTrattare come riservato

Figura 13: Un ETL riflette ogni nome di processo, i percorsi dei file aperti, i moduli e a seconda del profilo i nomi delle chiavi di registro; abilitare un provider personalizzato include anche il suo payload. Trattatelo come riservato: cattura al minimo necessario, accordo con l’altra parte, e un periodo di conservazione e cancellazione.

  • Un «tutto il PC è lento» che il Task Manager non sa spiegare si indaga con una traccia ETW a livello di OS — cattura con WPR, lettura con WPA. wpr.exe è incluso in Windows 8.1 e successivi, quindi vale una divisione di catturare nell’ambiente del cliente, portare a casa l’ETL e leggerlo in WPA sulla vostra macchina.
  • La cattura è i tre passi wpr -start GeneralProfile -filemode → riproduci → wpr -stop trace.etl. Se potete riprodurre, File mode entro pochi minuti; se aspettate, Memory mode (ring buffer). Più a lungo non è meglio.
  • WPA si può iniziare una volta interiorizzati tre punti: la regola d’oro delle tabelle (a sinistra della barra oro = raggruppamento), lo zoom dell’intervallo di tempo e la configurazione dei simboli (la vostra app ha bisogno dei PDB).
  • Se la CPU è alta, percorrete processo → stack → funzione in CPU Usage (Sampled). Se la CPU è bassa ed è comunque lento, percorrete la catena NewThreadStack (cosa stava facendo quando si è fermato) → Waits (quanto ha aspettato) → ReadyingProcess e ReadyThreadStack (chi lo ha svegliato) fino alla radice in CPU Usage (Precise).
  • Per il disco, vedete «tempo speso in coda» dalla differenza tra Disk Usage IO Time e Service Time, e identificate la causa (se il dispositivo stesso è lento, o chi ha fatto la coda) da Service Time e dalla scomposizione per processo, percorso e stack. Un avvio lento si può catturare con wpr -boottrace.
  • Il pattern di lavoro è (1) inchiodare l’ora (2) zoomare sull’intervallo (3) classificare CPU, attesa o I/O (4) ripetere ipotesi → zoom → stack. Trattate un ETL come riservato perché contiene informazioni interne.

Lo schermo di WPA è intimidatorio, e tutti si perdono nella prima ora. Una volta che le due spine dorsali — «a sinistra della barra oro è il raggruppamento» e «Sampled è dove ha bruciato, Precise è chi aspettava» — sono dentro, però, il resto è la stessa operazione ripetuta. La prossima volta che arriva una consulenza «la CPU ha margine ed è comunque lento», chiudete il Task Manager e catturate una traccia.

Articoli correlati

Aree di consulenza correlate

KomuraSoft LLC si occupa dell’indagine di problemi di prestazioni a livello di sistema come «tutto il PC è diventato lento e non so perché», «la CPU ha margine e l’app è comunque lenta» e «solo un ambiente specifico è estremamente lento ad avviarsi». Trattiamo come un unico incarico continuo il progetto di cattura con WPR/WPA (in quale ambiente, quale profilo, quanto catturare), l’analisi della traccia e la conseguente correzione lato app e lato impostazioni.

Riferimenti

  1. Microsoft Learn, Introduction to WPR. Sul fatto che WPR è uno strumento di registrazione delle prestazioni basato su ETW; sul fatto che l’edizione da riga di comando WPR.exe è inclusa in Windows 8.1 e successivi senza installazioni extra; sul suo rapporto con l’edizione GUI WPRUI.exe; e sull’idea di un profilo di registrazione.  2 3 4

  2. Microsoft Learn, Windows Performance Analyzer. Sul fatto che WPA è incluso nel Windows ADK, è uno strumento di analisi che costruisce grafici e tabelle di dati da eventi ETW registrati da WPR, Xperf e simili, e può aprire e analizzare qualsiasi file ETL.  2 3 4

  3. Microsoft Learn, WPR Command-Line Options. Sulla sintassi di wpr -start/-stop/-cancel/-status/-profiles; su -filemode (il default è memory mode); sullo specificare più profili insieme; sulle boot trace con -boottrace (addboot/stopboot/cancelboot); e sulla registrazione di transizioni On/Off come Boot con -onoffscenario.  2 3 4 5 6

  4. Microsoft Learn, CPU Analysis. Definizioni delle colonne del grafico CPU Usage (Precise) (NewThreadStack, ReadyThreadStack, ReadyingProcess, Waits e simili); la procedura di espandere ReadyThreadStack e percorrere ReadyingProcess/ReadyingThread fino alla causa radice di un’attesa; e come distinguere uno sveglio da KiTimerExpiration (un’attesa di timer) o dal completamento I/O.  2 3 4 5

  5. Microsoft Learn, Troubleshoot processes and threads by using WPR and WPA. Configurazioni come leggere CPU Usage (Sampled) come Process→Stack su utilizzo CPU alto, e usare CPU Usage (Precise) Readying Process, Readying Thread, Readying Stack e la colonna Wait nell’analisi delle attese; e una tabella di corrispondenza di profili e grafici per sintomo.  2

  6. Microsoft Learn, Exercise 2 - Evaluate Fast Startup Using Windows Performance Toolkit. Sul fatto che CPU Usage (Sampled) è campionamento a un intervallo di circa 1 millisecondo e l’attività breve tra i campioni non viene registrata; sulla procedura di percorrere processo → thread → stack per identificare la scomposizione del consumo CPU; e sul significato di Disk Usage IO Time (incluso il tempo di coda) e Disk Service Time (tempo di elaborazione del disco).  2 3 4

  7. Microsoft Learn, Exercise 3 - Understand Critical Path and Wait Analysis. L’idea dell’analisi del critical path (la classificazione Running / Ready / Waiting); il significato delle colonne della tabella CPU Usage (Precise) NewThreadStack, ReadyThreadStack, ReadyingProcess, Waits, Ready e simili; e la procedura di percorrere a turno il thread che ha svegliato per sbrogliare una catena di ritardi.  2 3

  8. Microsoft Learn, Loading Symbols. Sul fatto che quando _NT_SYMBOL_PATH non è impostato WPA fa riferimento per default al server pubblico dei simboli Microsoft (msdl.microsoft.com); sull’aggiungere un percorso PDB per i propri componenti; e sul fatto che WPR genera PDB per i simboli gestiti .NET in una cartella .ngenpdb accanto alla traccia e WPA li consulta automaticamente.  2 3

  9. Microsoft Learn, Built-in Recording Profiles. L’elenco dei profili di registrazione built-in di WPR (CPU usage, Disk I/O activity, File I/O activity, Registry I/O activity, Networking I/O activity e altri) e cosa registra ciascun profilo. 

  10. Microsoft Learn, Logging Mode. Sul fatto che le modalità di registrazione sono File (un file continuo) e Memory (un buffer circolare in memoria) e il default è Memory; sul fatto che Memory è adatto a un problema di cui non conoscete i tempi e gli eventi più vecchi vengono sovrascritti; e sul fatto che l’unico tetto di File è lo spazio disco libero e un file troppo grande può diventare inanalizzabile in WPA.  2

  11. Microsoft Learn, WPR How-to Topics. Sulla procedura per avviare e fermare una registrazione in WPRUI; sulla scelta di un profilo, del livello di dettaglio e di Logging mode; e sulla cautela che una registrazione lunga può rendere il file enorme e inanalizzabile in WPA, quindi andrebbe scelta Memory mode.  2

  12. Microsoft Learn, Graph Explorer. Sul fatto che la finestra Graph Explorer elenca miniature di grafici in categorie come System Activity, Computation, Storage e Memory; e sul fatto che trascinate un grafico sulla scheda Analysis per visualizzarlo insieme a una tabella. 

  13. Microsoft Learn, Graphs (WPA Features). La visualizzazione Flame graph di WPA; la struttura della tabella in cui le colonne a sinistra della barra oro sono raggruppamento e le colonne a destra della barra blu sono aggregati; e il preset Flame by Process, Stack di CPU Usage (Sampled).  2

  14. Microsoft Learn, Load Symbols or Configure Symbol Paths. Sul caricare i simboli con Load Symbols dal menu Trace di WPA; e sulla procedura per impostare e cambiare il percorso dei simboli nella finestra Configure Symbol Paths. 

  15. Microsoft Learn, List of WPA Graphs. L’elenco dei grafici disponibili in WPA. Preset di Disk Usage come IO Time by Process, IO Type; Service Time by Process, Path Name, Stack; Utilization by Process, Path Name, Stack; e preset di File I/O come Duration by Process, Thread, Type.  2 3

Articoli recenti con gli stessi tag per approfondire argomenti vicini.

Queste pagine collocano l’argomento in un contesto più ampio di servizi e decisioni.

L’articolo è direttamente collegato ai servizi seguenti.

Domande frequenti

Domande che ricorrono nelle consulenze sull’argomento dell’articolo.

Dove ottengo WPR e WPA? Posso usarli in un ambiente del cliente in cui non posso installare software?
Lo strumento di cattura wpr.exe (l'edizione da riga di comando) è incluso in Windows 8.1 e successivi, quindi potete usarlo senza installazioni extra. L'edizione GUI, WPRUI, e lo strumento di analisi WPA (Windows Performance Analyzer) sono inclusi nel Windows ADK (Windows Assessment and Deployment Kit) e richiedono un'installazione separata. In pratica, se spezzate il lavoro come «nell'ambiente del cliente catturate solo un file ETL con il wpr.exe standard dell'OS, lo portate a casa e lo analizzate in WPA sulla vostra macchina», potete indagare le prestazioni a livello di sistema anche in un sito in cui non potete aggiungere software.
Perché è lento quando il Task Manager mostra CPU di riserva? Cosa posso vedere in WPA?
Quando l'utilizzo della CPU è basso ed è comunque lento, il lavoro non è incapace di usare la CPU — è fermo «in attesa di qualcosa». Contesa sui lock, attesa che un I/O sincrono finisca e attesa che un altro processo risponda sono tipici. Il Task Manager mostra solo il risultato, l'utilizzo; CPU Usage (Precise) di WPA mostra, da un record per context switch, dove il thread ha iniziato ad aspettare (NewThreadStack), quanto ha aspettato (Waits) e chi lo ha svegliato (ReadyingProcess, ReadyThreadStack). Percorrendo la parte che lo ha fatto aspettare, potete identificare «il colpevole della lentezza» fino alla funzione.
Per quanto tempo dovrei catturare una traccia? Il file non diventa enorme?
Se potete riprodurre il problema, la baseline è partire subito prima della riproduzione, fermarsi subito dopo e restare entro pochi minuti. Il default di WPR è Memory mode, che registra su un buffer circolare in memoria; gli eventi più vecchi vengono sovrascritti, quindi è adatto ad aspettare un problema di cui non conoscete i tempi. File mode, con -filemode, tiene tutto in un file continuo, ma l'unico tetto è lo spazio disco libero, e un file troppo grande può diventare inanalizzabile in WPA. Usate Memory mode per un'attesa lunga, File mode per una riproduzione breve e affidabile.
Come dovrei scegliere tra PerfView e WPA?
Entrambi gli strumenti trattano tracce ETW, ma i punti di forza differiscono. PerfView ha una comprensione profonda del runtime .NET ed è forte nell'indagine specifica delle app gestite come GC, allocazione e JIT. WPA è adatto a leggere CPU, disco, I/O file, alimentazione e simili a livello di OS attraverso grafici e tabelle, ed è la prima scelta quando «non è una app specifica ma tutto il PC è lento», «sono coinvolti più processi» o «si sospetta qualcosa fuori dall'app (antivirus, un driver, un altro processo)». Una regola empirica è PerfView per la lentezza della vostra app .NET da sola, WPR/WPA per la lentezza di tutto il sistema.
Va bene eseguire WPR nell'ambiente di produzione di un cliente?
Una cattura breve è comune in pratica, ma non è incondizionatamente sicura. ETW è leggero, ma registrare un grande volume di eventi con gli stack consuma comunque una certa quantità di CPU e memoria. Incorporate considerazioni come partire subito prima del passo di riproduzione e fermarsi subito dopo, tenere la cattura entro pochi minuti ed eseguirla in un momento con poco impatto sul business nello stesso processo di approvazione di qualsiasi modifica ordinaria. Inoltre, un file ETL contiene informazioni interne del sistema come nomi di processo, percorsi di file e informazioni sugli eseguibili, quindi dovreste decidere in anticipo come verrà trattato se esce dall'azienda (minimizzazione, periodo di conservazione, cancellazione).

Profilo dell’autore

Pagina di presentazione dell’autore dell’articolo.

Go Komura

Rappresentante di KomuraSoft LLC

Specializzato nello sviluppo di software Windows, nella consulenza tecnica e nell’analisi dei malfunzionamenti, soprattutto nei progetti con sistemi esistenti e guasti difficili da riprodurre.

Torna al blog