aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/lwtrace/perf.cpp
blob: b3f109c1beac67a05670260bc1362f0f3bfd72eb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include "perf.h" 
 
#include "probes.h"

#include <util/system/datetime.h> 
#include <util/system/hp_timer.h> 
 
namespace NLWTrace { 
    LWTRACE_USING(LWTRACE_INTERNAL_PROVIDER); 
 
    TCpuTracker::TCpuTracker() 
        : MinReportPeriod(NHPTimer::GetCyclesPerSecond()) 
    { 
        ResetStats(); 
    } 
 
    void TCpuTracker::Enter() { 
        LastTs = GetCycleCount(); 
    } 
 
    void TCpuTracker::Exit(const TProbe* probe) { 
        ui64 exitTs = GetCycleCount(); 
        if (exitTs < LastTs) { 
            return; // probably TSC was reset 
        } 
        ui64 cycles = exitTs - LastTs; 
        LastTs = exitTs; 
 
        AddStats(probe, cycles); 
    } 
 
    void TCpuTracker::AddStats(const TProbe* probe, ui64 cycles) { 
        if (MaxCycles < cycles) { 
            MaxProbe = probe; 
            MaxCycles = cycles; 
        } 
        if (MinCycles > cycles) { 
            MinCycles = cycles; 
        } 
        ProbeCycles += cycles; 
        Count++; 
 
        if (LastTs - LastReportTs > MinReportPeriod) { 
            Report(); 
        } 
    } 
 
    void TCpuTracker::ResetStats() { 
        MaxCycles = 0; 
        MaxProbe = nullptr; 
        MinCycles = ui64(-1); 
        ProbeCycles = 0; 
        Count = 0; 
    } 
 
    void TCpuTracker::Report() { 
        if (!Reporting) { 
            Reporting = true; 
            ReportNotReentrant(); 
            Reporting = false; 
        } 
    } 
 
    void TCpuTracker::ReportNotReentrant() { 
        if (LastReportTs && Count > 0 && LastTs > LastReportTs) { 
            ui64 reportPeriod = LastTs - LastReportTs; 
            double share = double(ProbeCycles) / reportPeriod; 
            double minMs = MilliSeconds(MinCycles); 
            double maxMs = MilliSeconds(MaxCycles); 
            double avgMs = MilliSeconds(ProbeCycles) / Count; 
            LastReportTs = LastTs; 
            ResetStats(); 
            LWPROBE(PerfReport, share, minMs, maxMs, avgMs); 
        } else { 
            LastReportTs = LastTs; 
            ResetStats(); 
        } 
    } 
 
    double TCpuTracker::MilliSeconds(ui64 cycles) { 
        return NHPTimer::GetSeconds(cycles) * 1000.0; 
    } 
 
}