forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwindowed_analyzer.cc
127 lines (110 loc) · 4.35 KB
/
windowed_analyzer.cc
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/latency/windowed_analyzer.h"
namespace ui {
void FrameRegionResult::AsValueInto(
base::trace_event::TracedValue* state) const {
// We don't report sample_count, since that is reported at a higher level.
state->SetDouble("value", value);
state->SetDouble("start", window_begin.since_origin().InMillisecondsF());
state->SetDouble("duration", (window_end - window_begin).InMillisecondsF());
}
namespace frame_metrics {
WindowedAnalyzer::WindowedAnalyzer(
const WindowedAnalyzerClient* client,
const SharedWindowedAnalyzerClient* shared_client)
: client_(client), shared_client_(shared_client) {
window_queue_.reserve(shared_client->max_window_size);
}
WindowedAnalyzer::~WindowedAnalyzer() = default;
void WindowedAnalyzer::ResetWorstValues() {
results_.reset();
}
void WindowedAnalyzer::ResetHistory() {
total_weight_ = 0;
accumulator_ = 0;
root_accumulator_ = 0;
square_accumulator_ = Accumulator96b();
window_queue_.resize(0);
}
void WindowedAnalyzer::AddSample(uint32_t value,
uint32_t weight,
uint64_t weighted_value,
uint64_t weighted_root,
const Accumulator96b& weighted_square) {
DCHECK_GT(weight, 0u);
DCHECK_EQ(weighted_value, static_cast<uint64_t>(weight) * value);
// Remove old values from the accumulators.
if (window_queue_.size() >= shared_client_->max_window_size) {
const uint32_t old_value = window_queue_.front().value;
const uint32_t old_weight = window_queue_.front().weight;
window_queue_.pop_front();
// Re-calculate some of the old values here. Although squared and root are
// passed in, we've only stored the original value to reduce memory usage.
total_weight_ -= old_weight;
accumulator_ -= static_cast<uint64_t>(old_weight) * old_value;
// Casting the whole rhs is important to ensure rounding happens at a place
// equivalent to when it was added.
root_accumulator_ -= static_cast<uint64_t>(
old_weight *
std::sqrt(static_cast<uint64_t>(old_value) << kFixedPointRootShift));
square_accumulator_.Subtract(Accumulator96b(old_value, old_weight));
}
// Verify overflow isn't an issue.
// square_accumulator_ has DCHECKs internally, so we don't worry about
// checking that here.
DCHECK_LT(weighted_value,
std::numeric_limits<decltype(accumulator_)>::max() - accumulator_);
DCHECK_LT(weighted_root,
std::numeric_limits<decltype(root_accumulator_)>::max() -
root_accumulator_);
DCHECK_LT(weight, std::numeric_limits<decltype(total_weight_)>::max() -
total_weight_);
window_queue_.push_back({value, weight});
total_weight_ += weight;
accumulator_ += weighted_value;
root_accumulator_ += weighted_root;
square_accumulator_.Add(weighted_square);
if (window_queue_.size() >= shared_client_->max_window_size) {
bool initialize_results = !results_;
if (initialize_results)
results_.emplace();
UpdateWorst(accumulator_, &results_->mean, initialize_results);
UpdateWorst(root_accumulator_, &results_->root, initialize_results);
UpdateWorst(square_accumulator_, &results_->square, initialize_results);
}
}
FrameRegionResult WindowedAnalyzer::ComputeWorstMean() const {
FrameRegionResult result;
if (results_) {
result = results_->mean;
} else {
UpdateWorst(accumulator_, &result, true);
}
result.value = client_->TransformResult(result.value);
return result;
}
FrameRegionResult WindowedAnalyzer::ComputeWorstRMS() const {
FrameRegionResult result;
if (results_) {
result = results_->square;
} else {
UpdateWorst(square_accumulator_, &result, true);
}
result.value = client_->TransformResult(std::sqrt(result.value));
return result;
}
FrameRegionResult WindowedAnalyzer::ComputeWorstSMR() const {
FrameRegionResult result;
if (results_) {
result = results_->root;
} else {
UpdateWorst(root_accumulator_, &result, true);
}
result.value = client_->TransformResult((result.value * result.value) /
kFixedPointRootMultiplier);
return result;
}
} // namespace frame_metrics
} // namespace ui