blob: 03b68586eaab53ed57f1aaafe0a12e0929a55377 (
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;
}
}
|