windows - Sådan finder du ledig tid (og netværk IO tid osv.) i XPerf?

Indlæg af Hanne Mølgaard Plasc

Problem



Lad os sige, at jeg har et konstrueret program:


#include <Windows.h>

void useless\_function()
{
    Sleep(5000);
}

void useful\_function()
{
    // ... do some work
    useless\_function();
    // ... do some more work
}

int main()
{
    useful\_function();
    return 0;
}


Mål : Jeg vil have profiler at fortælle mig useful\_function() behøver unødvendigt at ringe useless\_function(), som venter på ingen indlysende grunde. Under XPerf vises det ikke i nogen af ​​de grafer jeg har, fordi opkaldet til WaitForMultipleObjects() synes at blive opgjort til Idle.exe i stedet for mit eget program.


Og her er xperf kommandolinjen, som jeg kører i øjeblikket:


xperf -on Latency -stackwalk Profile


Nogle ideer?


(Dette er ikke begrænset til ventefunktioner. Ovennævnte kan være blevet løst ved at placere breakpoints på NtWaitForMultipleObjects. Ideelt set kunne der være en måde at se stakprøven, der tager meget vægur tid i modsætning til kun CPU-tid)

Bedste reference


Jeg tror, ​​hvad du leder efter, er Vent analyse med klar tråd funktionalitet i Xperf. Det fanger hver kontekstomskifter og giver dig opkaldsstakken af ​​tråden, når den vågner op fra søvn (eller en ellers blokeret operation). I dit tilfælde ville du se stakken lige efter opkaldet søvn (5000) samt tid tilbringe sove.


Funktionaliteten er lidt uklart at bruge. Men det er heldigvis godt beskrevet her:


Brug Xperfs Vent Analyse til Fejlfinding af Application-Performance [11]

Andre referencer 1


Vent Analyse er måden at gøre dette på. Du burde:



  • Optag CSWITCH-udbyderen for at få alle kontekstomskiftere

  • Optag opkaldstabler på kontekstomskiftere ved at tilføje + CSWITCH til dit 'stackwalk argument'

  • Sandsynligvis optag opkaldstabler på den færdige tråd for at få flere oplysninger om, hvem der har læst dig (dvs. hvem har udgivet Mutex eller CS eller semaphore og hvor) ved at tilføje + READYTHREAD til din -staskewalk



Så bruger du CPU-brug (Præcis) i WPA (eller xperfview, men det er gamle) for at se på kontekstomskifterne og finde, hvor din TimeSinceLast er højt på en tråd, der ikke skal gå i tomgang. Du vil typisk have kolonnerne i CPU-brug (Præcis) i denne slags ordre:



  • NewProcess (din proces bliver slået til)

  • NewThreadId

  • NewThreadStack

  • ReadyingProcess (som lavede din tråd klar til at køre)

  • ReadyingThreadId (valgfrit)

  • ReadyThreadStack (valgfrit, kræver + ReadyThread on-stackwalk)

  • Orange bar

  • Grev

  • TimeSinceLast (os) - Sorter efter denne kolonne, som regel

  • Uanset hvilke andre kolonner du vil have



For detaljer se disse artikler fra min blog:
 - https://randomascii.wordpress.com/2014/08/19/etw-training-videos-available-now/
 - https://randomascii.wordpress.com/2012/06/19/wpaxperf-trace-analysis-reimagined/[12][13]

Andre referencer 2


Denne 'profiler' vil fortælle dig - bare pause det et par gange og se på stakken. Hvis do some work tager 5 sekunder og do some more work tager 5 sekunder, så vil 33\% af tiden blive så stor som denne


main: calling useful\_function
useful\_function: calling useless\_function
useless\_function: calling Sleep


Så omtrent 33\% af dine stakkeprøver viser nøjagtigt det. En hvilken som helst linje af kode, der koster en vis brøkdel af væguretiden, vil ses på omtrent den brøkdel af prøver.


På resten af ​​prøverne vil du se det gøre de andre ting.


Der er automatiserede profiler, der gør det samme på en mere smuk måde, som Zoom og LTProf, selvom de ikke viser dig prøverne. [14] [15]


Jeg kiggede på xperf doc, og prøvede at finde ud af om du kunne få stakprøver på væguretiden og få procentpoint på opløsning på linjeniveau. Det ser ud til at du skal være på Windows 7 eller Vista. De forstyrrer kun funktioner, ikke linjer, som hvis du har realistisk store funktioner, er vigtig. Jeg kunne ikke finde ud af, hvordan man får adgang til de enkelte prøver, som jeg synes er vigtigt for at se hvorfor programmet bruger sin tid.