Misurare le prestazioni dell'applicazione analizzando l'utilizzo della CPU (C#, Visual Basic, C++, F#)

Individuare i problemi di prestazioni durante il debug con lo strumento di diagnostica Utilizzo CPU integrato nel debugger. È anche possibile analizzare l'utilizzo della CPU senza un debugger collegato o specificando come destinazione un'app in esecuzione. Per altre informazioni, vedere Eseguire gli strumenti di profilatura con o senza il debugger.

Quando il debugger viene sospeso, lo strumento Utilizzo CPU nella finestra Strumenti di diagnostica raccoglie informazioni sulle funzioni in esecuzione nell'applicazione. Vengono indicate le funzioni che stavano eseguendo un'operazione e un grafico della sequenza temporale consente di concentrarsi su segmenti specifici della sessione di campionamento.

Importante

Gli strumenti di diagnostica integrati nel debugger sono supportati per lo sviluppo .NET in Visual Studio, tra cui ASP.NET, ASP.NET Core e per lo sviluppo nativo/C++. È necessario il carico di lavoro di Visual Studio corrispondente. Per Windows 8 e versioni successive è necessario eseguire gli strumenti di profilatura con il debugger, nella finestra Strumenti di diagnostica.

Questa esercitazione illustra come:

  • Raccogliere i dati di Utilizzo CPU
  • Analizzare i dati d'uso della CPU

Se l'utilizzo della CPU non fornisce i dati necessari, altri strumenti di profilatura nel profiler prestazioni forniscono diversi tipi di informazioni che potrebbero essere utili per l'utente. In molti casi il collo di bottiglia delle prestazioni dell'applicazione può dipendere da un fattore diverso dalla CPU, ad esempio la memoria, il rendering dell'interfaccia utente o il tempo di richiesta di rete.

Passaggio 1: Raccogliere i dati di utilizzo della CPU

  1. Aprire il progetto per cui si vuole eseguire il debug in Visual Studio e impostare un punto di interruzione nell'applicazione in corrispondenza del punto in cui si vuole esaminare l'utilizzo della CPU.

  2. Impostare un secondo punto di interruzione alla fine della funzione o dell'area di codice da analizzare.

    Impostando i due punti di interruzione è possibile limitare la raccolta dei dati per le parti di codice che si vuole analizzare.

  3. La finestra Strumenti di diagnostica viene visualizzata automaticamente, a meno che non sia stata disattivata. Per visualizzare di nuovo la finestra, fare clic su Debug>Finestre>Mostra strumenti di diagnostica.

  4. È possibile scegliere se visualizzare Utilizzo CPU, Utilizzo memoria o entrambi usando l'impostazione Seleziona strumenti della barra degli strumenti. Se si usa Visual Studio Enterprise, è anche possibile abilitare o disabilitare IntelliTrace in Strumenti>Opzioni>IntelliTrace.

    Screenshot that shows Diagnostics Tools.

    Screenshot that shows Diagnostics Tools.

    In questa sede ci si occupa principalmente dell'utilizzo della CPU, quindi verificare che l'opzione Utilizzo CPU è abilitata (è abilitata per impostazione predefinita).

  5. Fare clic su Debug>Avvia debug (o Avvia sulla barra degli strumenti o F5).

    Al termine del caricamento dell'applicazione viene visualizzata la vista Riepilogo degli strumenti di diagnostica. Se è necessario aprire la finestra, fare clic su Debug>Finestre>Mostra strumenti di diagnostica.

    Screenshot that shows Diagnostics Tools Summary Tab.

    Screenshot that shows Diagnostics Tools Summary Tab.

    Per altre informazioni sugli eventi, vedere l'articolo relativo a come eseguire ricerche e applicare filtri nella scheda Eventi della finestra Strumenti di diagnostica.

  6. Eseguire lo scenario in cui viene raggiunto il primo punto di interruzione.

  7. Quando il debugger è in pausa, abilitare la raccolta dei dati relativi all'utilizzo della CPU e quindi aprire la scheda Utilizzo CPU.

    Screenshot that shows Diagnostics Tools enable CPU profiling.

    Screenshot that shows Diagnostics Tools enable CPU profiling.

    Quando si sceglie Registra profilo CPU Visual Studio avvia la registrazione delle funzioni e del tempo necessario per eseguirle. È possibile visualizzare i dati raccolti solo quando l'applicazione viene interrotta in un punto di interruzione.

  8. Premere F5 per eseguire l'applicazione fino al secondo punto di interruzione.

    Ora si hanno a disposizione i dati relativi alle prestazioni per l'applicazione, precisamente per l'area di codice compresa tra i due punti di interruzione.

    Il profiler inizia a preparare i dati di thread. Attendere il completamento.

    Screenshot that shows Diagnostics Tools preparing threads.

    Screenshot that shows Diagnostics Tools preparing threads.

    Lo strumento Utilizzo CPU consente di visualizzare il report nella scheda Utilizzo CPU.

    Screenshot that shows Diagnostics Tools CPU Usage Tab.

    Screenshot that shows Diagnostics Tools CPU Usage Tab.

  9. Se si vuole selezionare un'area di codice più specifica da analizzare, selezionare un'area nella sequenza temporale della CPU (deve essere un'area con dati di profilatura).

    Screenshot that shows Diagnostics Tools selecting a time segment.

    Screenshot that shows Diagnostics Tools selecting a time segment.

    A questo punto, è possibile iniziare ad analizzare i dati. In caso di problemi durante la raccolta o la visualizzazione dei dati, vedere Risolvere gli errori di profilatura e risolvere i problemi.

    Suggerimento

    Quando si tenta di identificare i problemi di prestazioni, eseguire più misurazioni. Le prestazioni variano naturalmente da run-to-run e i percorsi di codice vengono in genere eseguiti più lentamente alla prima esecuzione a causa del lavoro di inizializzazione monouso, ad esempio il caricamento di DLL, i metodi di compilazione JIT e l'inizializzazione delle cache. Prendendo più misurazioni, si ottiene un'idea migliore dell'intervallo e della median della metrica visualizzata, che consente di confrontare la prima volta rispetto alle prestazioni dello stato costante di un'area di codice.

Passaggio 2: Analizzare i dati di utilizzo della CPU

È consigliabile iniziare ad analizzare i dati esaminando l'elenco di funzioni in Utilizzo CPU, identificando le funzioni che svolgono la maggior parte del lavoro e quindi concentrandosi su ognuna di esse.

  1. Nell'elenco delle funzioni esaminare le funzioni che eseguono il maggior numero di operazioni.

    Screenshot that shows Diagnostics Tools CPU Usage Function List.

    Screenshot that shows Diagnostics Tools CPU Usage Function List.

    Suggerimento

    Le funzioni sono elencate in ordine a partire da quelle che svolgono la maggior parte del lavoro (non sono in ordine di chiamata). Ciò consente di identificare rapidamente le funzioni in esecuzione da più tempo.

  2. Nell'elenco delle funzioni fare doppio clic su una delle funzioni dell'applicazione che esegue molte operazioni.

    Quando si fa doppio clic su una funzione, la visualizzazione Funzioni viene aperta nel riquadro sinistro. Selezionare Visualizzazione chiamante/chiamato dal menu a discesa.

    Screenshot that shows Diagnostics Tools Caller Callee View.

    In questa visualizzazione la funzione selezionata viene visualizzata nell'intestazione e nella casella Funzione corrente (DoWork, in questo esempio). La funzione che ha chiamato la funzione corrente viene visualizzata a sinistra, in Funzioni chiamanti, e tutte le funzioni chiamate dalla funzione corrente sono riportate nella casella Funzioni chiamate sulla destra. Selezionare una delle due caselle per modificare la funzione corrente.

    Questa visualizzazione indica il tempo totale (ms) e la percentuale del tempo complessivo di esecuzione dell'applicazione dedicato al completamento della funzione. Corpo funzione indica anche la quantità totale di tempo (e la percentuale di tempo) impiegata nel corpo della funzione, escluso il tempo dedicato alle funzioni chiamanti e chiamate.

    Quando si fa doppio clic su una funzione viene aperta la visualizzazione Chiamante/Chiamato nel riquadro a sinistra.

    Screenshot that shows Diagnostics Tools Caller Callee View.

    In questa visualizzazione la funzione selezionata viene visualizzata nell'intestazione e nella casella Funzione corrente (GetNumber, in questo esempio). La funzione che ha chiamato la funzione corrente viene visualizzata a sinistra, in Funzioni chiamanti, e tutte le funzioni chiamate dalla funzione corrente sono riportate nella casella Funzioni chiamate sulla destra. Selezionare una delle due caselle per modificare la funzione corrente.

    Questa visualizzazione indica il tempo totale (ms) e la percentuale del tempo complessivo di esecuzione dell'applicazione dedicato al completamento della funzione. Corpo funzione indica anche la quantità totale di tempo (e la percentuale di tempo) impiegata nel corpo della funzione, escluso il tempo dedicato alle funzioni chiamanti e chiamate. In questo esempio 2367 su 2389 ms sono stati usati nel corpo della funzione e i 22 ms rimanenti nel codice esterno chiamato dalla funzione.

    Suggerimento

    Valori elevati in Corpo funzione possono indicare un collo di bottiglia delle prestazioni all'interno della funzione stessa.

  3. Per una visualizzazione più generale che mostra l'ordine di chiamata delle funzioni, selezionare Albero delle chiamate nell'elenco a discesa nella parte superiore del riquadro.

    Ogni area numerata nella figura si riferisce a un passaggio della procedura.

    Diagnostics Tools Call Tree

    Image Descrizione
    Step 1 Il nodo di livello principale nell'albero delle chiamate di Utilizzo CPU è uno pseudo-nodo
    Step 2 Nella maggior parte delle app, quando l'opzione Mostra codice esterno è disabilitata, il nodo di secondo livello è un nodo [Codice esterno] contenente il codice di sistema e di framework che avvia e arresta l'app, disegna l'interfaccia utente, controlla la pianificazione dei thread e fornisce altri servizi di basso livello all'app.
    Step 3 Gli elementi figlio del nodo di secondo livello sono i metodi del codice utente e le routine asincrone che vengono chiamati o creati dal codice di sistema o di framework di secondo livello.
    Step 4 I nodi figlio di un metodo contengono i dati solo per le chiamate del metodo padre. Quando l'opzione Mostra codice esterno è disabilitata, i metodi dell'app possono contenere anche un nodo [Codice esterno] .

    Di seguito sono riportate altre informazioni sui valori di colonna:

    • CPU totale indica la quantità di lavoro svolta dalla funzione e dalle funzioni chiamate dalla funzione. Valori elevati di CPU totale indicano le funzioni più dispendiose in generale.

    • CPU auto indica la quantità di operazioni eseguite dal codice nel corpo della funzione, escluse quelle eseguite dalle funzioni chiamate dalla funzione. Valori elevati di CPU auto possono indicare un collo di bottiglia delle prestazioni all'interno della funzione stessa.

    • Moduli Nome del modulo contenente la funzione o numero dei moduli contenenti le funzioni in un nodo [Codice esterno].

    Per visualizzare le chiamate di funzioni che usano la percentuale massima della CPU nella visualizzazione dell'albero delle chiamate, fare clic su Espandi percorso critico.

    Screenshot that shows Diagnostics Tools Hot Path.

    Nota

    Se nell'albero delle chiamate sono presenti porzioni di codice contrassegnate come codice "danneggiato" o "stack unwalkable", è probabile che siano stati eliminati eventi ETW (Event Tracing for Windows). Per risolvere il problema, provare a raccogliere nuovamente la stessa traccia.

Visualizzare codice esterno

Il codice esterno rappresenta funzioni nei componenti del sistema e del framework che vengono eseguite dal codice scritto. Include funzioni che avviano e arrestano l'app, disegnano l'interfaccia utente, controllano il threading e forniscono altri servizi di basso livello all'app. Nella maggior parte dei casi il codice esterno è poco interessante, per questo motivo lo strumento Utilizzo CPU raccoglie le funzioni esterne di un metodo utente in un unico nodo [Codice esterno] .

Per visualizzare i percorsi delle chiamate del codice esterno, scegliere Mostra codice esterno dall'elenco Visualizzazione filtro e quindi scegliere Applica.

Screenshot that shows Choose Filter View, then Show External Code.

Tieni presente che numerose catene di chiamate del codice esterno sono molto annidate, pertanto la larghezza della colonna Nome funzione può superare la larghezza di visualizzazione in quasi tutti i monitor, ad eccezione di quelli più grandi. Quando ciò si verifica, i nomi delle funzioni sono visualizzati come […].

Usare la casella di ricerca per trovare un nodo che si sta cercando, quindi usare la barra di scorrimento orizzontale per visualizzare i dati.

Suggerimento

Se si profila il codice esterno che chiama le funzioni di Windows, è necessario verificare di avere i file con estensione pdb più aggiornati. Senza questi file, le visualizzazioni dei rapporti elencherà i nomi delle funzioni di Windows enigmatici e difficile da comprendere. Per altre informazioni su come verificare di avere i file necessari, vedere Specifica di file di simboli con estensione pdb e di file di origine nel debugger.

Passaggi successivi

In questa esercitazione si è appreso come raccogliere e analizzare i dati d'uso della CPU. Se è già stata completata la presentazione del profiler, è possibile leggere un approccio generale all'ottimizzazione del codice usando gli strumenti di profilatura.

In questa esercitazione si è appreso come raccogliere e analizzare i dati di utilizzo della CPU durante il debug. Per altre informazioni sulla profilatura delle build di versione, è possibile usare il Profiler prestazioni.