Strumenti di diagnostica in parallelo (runtime di concorrenza)
Visual Studio fornisce supporto completo per il debug e la profilatura di applicazioni multithread.
Debug
Il debugger di Visual Studio include la finestra Stack paralleli, la finestra Attività parallele e la finestra Espressione di controllo parallelo. Per altre informazioni, vedere Procedura: Debug di un'applicazione parallela e Procedura: Usare la finestra Espressione di controllo parallelo.
Raccolta informazioni utente
Gli strumenti di profilatura forniscono tre visualizzazioni dati che visualizzano informazioni grafiche, tabulari e numeriche su come un'applicazione multithread interagisce con se stessa e con altri programmi. Le visualizzazioni consentono di identificare rapidamente le aree problematiche e di spostarsi da punti nelle visualizzazioni grafiche agli stack di chiamate, ai siti di chiamata e al codice sorgente. Per altre informazioni, vedere Visualizzatore di concorrenza.
Traccia eventi
Il runtime di concorrenza usa Event Tracing for Windows (ETW) per notificare strumenti di strumentazione, ad esempio profiler, quando si verificano vari eventi. Questi eventi includono quando un'utilità di pianificazione viene attivata o disattivata, quando un contesto inizia, termina, blocca, sblocca o restituisce e quando un algoritmo parallelo inizia o termina.
Gli strumenti, ad esempio il visualizzatore di concorrenza, usano questa funzionalità. Di conseguenza, in genere non è necessario usare direttamente questi eventi. Tuttavia, questi eventi sono utili quando si sviluppa un profiler personalizzato o quando si usano strumenti di traccia eventi come Windows Performance Toolkit.
Il runtime di concorrenza genera questi eventi solo quando la traccia è abilitata. Chiamare la funzione concurrency::EnableTracing per abilitare la traccia degli eventi e la funzione concurrency::D isableTracing per disabilitare la traccia.
Nella tabella seguente vengono descritti gli eventi generati dal runtime quando è abilitata la traccia eventi:
Evento | Descrizione | valore |
---|---|---|
concurrency::ConcRT_ProviderGuid | Identificatore del provider ETW per il runtime di concorrenza. | f7b697a3-4db5-4d3b-be71-c4d284e6592f |
concurrency::ContextEventGuid | Contrassegna gli eventi correlati ai contesti. | 5727a00f-50be-4519-8256-f7699871fecb |
concurrency::P PLParallelForEventGuid | Contrassegna l'ingresso e l'uscita per le chiamate all'algoritmo concurrency::p arallel_for . | 31c8da6b-6165-4042-8b92-949e315f4d84 |
concurrency::P PLParallelForeachEventGuid | Contrassegna l'ingresso e l'uscita per le chiamate all'algoritmo concurrency::p arallel_for_each . | 5cb7d785-9d66-465d-bae1-4611061b5434 |
concurrency::P PLParallelInvokeEventGuid | Contrassegna l'ingresso e l'uscita per le chiamate all'algoritmo concurrency::p arallel_invoke . | d1b5b133-ec3d-49f4-98a3-464d1a9e4682 |
concurrency::SchedulerEventGuid | Contrassegna gli eventi correlati all'Utilità di pianificazione. | e2091f8a-1e0a-4731-84a2-0dd57c8a5261 |
concurrency::VirtualProcessorEventGuid | Contrassegna gli eventi correlati ai processori virtuali. | 2f27805f-1676-4ecc-96fa-7eb09d44302f |
Il runtime di concorrenza definisce, ma non genera attualmente gli eventi seguenti. Il runtime riserva questi eventi per un uso futuro:
L'enumerazione concurrency::ConcRT_EventType specifica le possibili operazioni rilevate da un evento. Ad esempio, all'ingresso dell'algoritmo parallel_for
, il runtime genera l'evento PPLParallelForEventGuid
e fornisce CONCRT_EVENT_START
come operazione. Prima che l'algoritmo parallel_for
venga restituito, il runtime genera nuovamente l'evento PPLParallelForEventGuid
e fornisce CONCRT_EVENT_END
come operazione.
Nell'esempio seguente viene illustrato come abilitare la traccia per una chiamata a parallel_for
. Il runtime non traccia la prima chiamata a parallel_for
perché la traccia non è abilitata. La chiamata a consente al EnableTracing
runtime di tracciare la seconda chiamata a parallel_for
.
// etw.cpp
// compile with: /EHsc
#include <ppl.h>
using namespace concurrency;
int wmain()
{
// Perform some parallel work.
// Event tracing is disabled at this point.
parallel_for(0, 10000, [](int i) {
// TODO: Perform work.
});
// Enable tracing for a second call to parallel_for.
EnableTracing();
parallel_for(0, 10000, [](int i) {
// TODO: Perform work.
});
DisableTracing();
}
Il runtime tiene traccia del numero di volte in cui si chiama EnableTracing
e DisableTracing
. Pertanto, se si chiama EnableTracing
più volte, è necessario chiamare DisableTracing
lo stesso numero di volte per disabilitare la traccia.