Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/jfr/support/jfrAdaptiveSampler.hpp
41152 views
1
/*
2
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3
* Copyright (c) 2020, Datadog, Inc. All rights reserved.
4
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
*
6
* This code is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License version 2 only, as
8
* published by the Free Software Foundation.
9
*
10
* This code is distributed in the hope that it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
* version 2 for more details (a copy is included in the LICENSE file that
14
* accompanied this code).
15
*
16
* You should have received a copy of the GNU General Public License version
17
* 2 along with this work; if not, write to the Free Software Foundation,
18
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19
*
20
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21
* or visit www.oracle.com if you need additional information or have any
22
* questions.
23
*
24
*/
25
26
#ifndef SHARE_JFR_SUPPORT_JFRADAPTIVESAMPLER_HPP
27
#define SHARE_JFR_SUPPORT_JFRADAPTIVESAMPLER_HPP
28
29
#include "jfr/utilities/jfrAllocation.hpp"
30
#include "jfr/utilities/jfrRandom.hpp"
31
32
/*
33
* The terminology is mostly from the domain of statistics:
34
*
35
* Population - a set of elements of interest.
36
* Sample - a subset of elements from a population selected by a defined procedure.
37
* Sample point - an element of a sample (sub)set.
38
* Sampling interval - the distance between which measurements are taken, also referred to as 'nth selection'
39
* Debt - an error term, signifying the deviation from a configured set point.
40
* Amortization - a projection or strategy to recover accumulated debt.
41
* Window - as in time window or time frame. The sampler sees the evolution of the system in time slices, i.e. in windows.
42
* Rotate - the process of retiring an expired window and installing a new window with updated parameters.
43
*
44
* The adaptive sampler will guarantee a maximum number of sample points selected from a populuation
45
* during a certain time interval. It is using fixed size time windows and adjusts the sampling interval for the next
46
* window based on what it learned in the past. Each window has a set point, which is the target number of sample points
47
* to select. The sampler keeps a cumulative error term, called 'accumulated debt', which is a measure
48
* for how much the sampler is deviating from the set point over time. The maximum number of sample points selected
49
* during an individual window is the set point + the accumulated debt.
50
* The 'accumulated debt' also works as a 'spike damper', smoothing out the extremes in a way that the overall
51
* target rate is obeyed without highly over- or under-sampled windows.
52
*
53
* Sample point selection is defined by a sampling interval, which gives instructions for selecting the 'nth' element
54
* in a population. Which 'nth' to select is a random variable from a geometric distribution, recalculated for each window.
55
*
56
* Each window is configured individually, by an instance of the JfrSamplerParams struct. On window expiration,
57
* but before switching in the next window, the sampler calls a subclass with the just expired window as an argument.
58
.* A subclass can inspect the window to study the history of the system and also get an overview of how the sampler
59
* is performing to help draw inferences. Based on what it learned, it can choose to let the sampler re-apply an updated
60
* set of parameters to the next, upcoming, window. This is a basic feedback control loop to be developed further,
61
* perhaps evolving more elaborate sampling schemes in the future.
62
*
63
* Using the JfrAdaptiveSampler, we can let a user specify at a high level, for example that he/she would like a
64
* maximum rate of n sample points per second. Naturally, lower rates will be reported if the system does not produce
65
* a population to sustain the requested rate, but n per second is respected as a maximum limit, hence it will never
66
* report a rate higher than n per second.
67
*
68
* One good use of the sampler is to employ it as a throttler, or regulator, to help shape large data sets into smaller,
69
* more managable subsets while still keeping the data somewhat representative.
70
*
71
*/
72
73
struct JfrSamplerParams {
74
size_t sample_points_per_window; // The number of sample points to target per window.
75
size_t window_duration_ms;
76
size_t window_lookback_count; // The number of data points (windows) to include when calculating a moving average for the population size.
77
mutable bool reconfigure; // The sampler should issue a reconfiguration because some parameter changed.
78
};
79
80
class JfrSamplerWindow : public JfrCHeapObj {
81
friend class JfrAdaptiveSampler;
82
private:
83
JfrSamplerParams _params;
84
volatile int64_t _end_ticks;
85
size_t _sampling_interval;
86
size_t _projected_population_size;
87
mutable volatile size_t _measured_population_size;
88
89
JfrSamplerWindow();
90
void initialize(const JfrSamplerParams& params);
91
size_t max_sample_size() const;
92
bool is_expired(int64_t timestamp) const;
93
bool sample() const;
94
bool sample(int64_t timestamp, bool* is_expired) const;
95
96
public:
97
size_t population_size() const;
98
size_t sample_size() const;
99
intptr_t debt() const;
100
intptr_t accumulated_debt() const;
101
const JfrSamplerParams& params() const {
102
return _params;
103
}
104
};
105
106
class JfrAdaptiveSampler : public JfrCHeapObj {
107
private:
108
JfrPRNG _prng;
109
JfrSamplerWindow* _window_0;
110
JfrSamplerWindow* _window_1;
111
const JfrSamplerWindow* _active_window;
112
double _avg_population_size;
113
double _ewma_population_size_alpha;
114
size_t _acc_debt_carry_limit;
115
size_t _acc_debt_carry_count;
116
117
void rotate_window(int64_t timestamp);
118
void rotate(const JfrSamplerWindow* expired);
119
const JfrSamplerWindow* active_window() const;
120
JfrSamplerWindow* next_window(const JfrSamplerWindow* expired) const;
121
void install(const JfrSamplerWindow* next);
122
123
size_t amortize_debt(const JfrSamplerWindow* expired);
124
size_t derive_sampling_interval(double sample_size, const JfrSamplerWindow* expired);
125
size_t project_population_size(const JfrSamplerWindow* expired);
126
size_t project_sample_size(const JfrSamplerParams& params, const JfrSamplerWindow* expired);
127
JfrSamplerWindow* set_rate(const JfrSamplerParams& params, const JfrSamplerWindow* expired);
128
129
void configure(const JfrSamplerParams& params);
130
const JfrSamplerWindow* configure(const JfrSamplerParams& params, const JfrSamplerWindow* expired);
131
132
protected:
133
volatile int _lock;
134
JfrAdaptiveSampler();
135
virtual ~JfrAdaptiveSampler();
136
virtual bool initialize();
137
virtual const JfrSamplerParams& next_window_params(const JfrSamplerWindow* expired) = 0;
138
void reconfigure();
139
140
public:
141
bool sample(int64_t timestamp = 0);
142
};
143
144
/* GTEST support */
145
class JfrGTestFixedRateSampler : public JfrAdaptiveSampler {
146
private:
147
JfrSamplerParams _params;
148
double _sample_size_ewma;
149
public:
150
JfrGTestFixedRateSampler(size_t sample_points_per_window, size_t window_duration_ms, size_t lookback_count);
151
virtual bool initialize();
152
const JfrSamplerParams& next_window_params(const JfrSamplerWindow* expired);
153
};
154
155
#endif // SHARE_JFR_SUPPORT_JFRADAPTIVESAMPLER_HPP
156
157