gem5 v24.0.0.0
Loading...
Searching...
No Matches
power_state.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015-2017, 2019-2020 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#include "sim/power_state.hh"
39
40#include <cassert>
41
42#include "base/logging.hh"
43#include "base/trace.hh"
44#include "debug/PowerDomain.hh"
45#include "sim/cur_tick.hh"
46#include "sim/power_domain.hh"
47#include "sim/serialize.hh"
48
49namespace gem5
50{
51
52PowerState::PowerState(const PowerStateParams &p) :
53 SimObject(p), _currState(p.default_state),
54 possibleStates(p.possible_states.begin(),
55 p.possible_states.end()),
56 stats(*this)
57{
58 for (auto &pm: p.leaders) {
59 // Register this object as a follower. This object is
60 // dependent on pm for power state transitions
61 pm->addFollower(this);
62 }
63}
64
65void
67{
68 // Only a power domain can register as dependant of a power stated
69 // object
70 controlledDomain = pwr_dom;
71 DPRINTF(PowerDomain, "%s is registered as controlled by %s \n",
72 pwr_dom->name(), name());
73}
74
75void
77{
78 unsigned int currState = (unsigned int)_currState;
79
80 SERIALIZE_SCALAR(currState);
82}
83
84void
86{
87 unsigned int currState;
88
89 UNSERIALIZE_SCALAR(currState);
91
92 _currState = enums::PwrState(currState);
93}
94
95void
96PowerState::set(enums::PwrState p)
97{
98 // Check if this power state is actually allowed by checking whether it is
99 // present in pwrStateToIndex-dictionary
101 "Cannot go to %s in %s \n", enums::PwrStateStrings[p], name());
102
103 // Function should ideally be called only when there is a state change
104 if (_currState == p) {
105 warn_once("PowerState: Already in the requested power state, "
106 "request ignored");
107 return;
108 }
109
110 // No need to compute stats if in the same tick, update state though. This
111 // can happen in cases like a) during start of the simulation multiple
112 // state changes happens in init/startup phase, b) one takes a decision to
113 // migrate state but decides to reverts back to the original state in the
114 // same tick if other conditions are not met elsewhere.
115 // Any state change related stats would have been recorded on previous call
116 // to this function.
117 if (prvEvalTick == curTick() && curTick() != 0) {
118 warn("PowerState: More than one power state change request "
119 "encountered within the same simulation tick");
120 _currState = p;
121 return;
122 }
123
124 // Record stats for previous state.
125 computeStats();
126
127 _currState = p;
128
130
131 // Update the domain this object controls, if there is one
132 if (controlledDomain) {
134 }
135
136}
137
138enums::PwrState
140{
141 // If the object is asked to match a power state, it has to be a follower
142 // and hence should not have a pointer to a powerDomain
143 assert(controlledDomain == nullptr);
144
145 // If we are already in this power state, ignore request
146 if (_currState == p) {
147 DPRINTF(PowerDomain, "Already in p-state %s requested to match \n",
148 enums::PwrStateStrings[p]);
149 return _currState;
150 }
151
152 enums::PwrState old_state = _currState;
153 if (possibleStates.find(p) != possibleStates.end()) {
154 // If this power state is allowed in this object, just go there
155 set(p);
156 } else {
157 // Loop over all power states in this object and find a power state
158 // which is more performant than the requested one (considering we
159 // cannot match it exactly)
160 for (auto rev_it = possibleStates.crbegin();
161 rev_it != possibleStates.crend(); rev_it++) {
162 if (*(rev_it) <= p) {
163 // This power state is the least performant power state that is
164 // still more performant than the requested one
165 DPRINTF(PowerDomain, "Best match for %s is %s \n",
166 enums::PwrStateStrings[p],
167 enums::PwrStateStrings[*(rev_it)]);
168 set(*(rev_it));
169 break;
170 }
171 }
172 }
173 // Check if the transition happened
174 // The only case in which the power state cannot change is if the
175 // object is already at in its most performant state.
176 warn_if((_currState == old_state) &&
178 "Transition to power state %s was not possible, SimObject already"
179 " in the most performance state %s",
180 enums::PwrStateStrings[p], enums::PwrStateStrings[_currState]);
181
183 return _currState;
184}
185
186void
188{
189 // Calculate time elapsed from last (valid) state change
190 Tick elapsed_time = curTick() - prvEvalTick;
191
192 stats.pwrStateResidencyTicks[_currState] += elapsed_time;
193
194 // Time spent in CLK_GATED state, this might change depending on
195 // transition to other low power states in respective simulation
196 // objects.
197 if (_currState == enums::PwrState::CLK_GATED) {
198 stats.ticksClkGated.sample(elapsed_time);
199 }
200
202}
203
206{
207 // Get residency stats
209 statistics::VCounter residencies;
211
212 // Account for current state too!
213 Tick elapsed_time = curTick() - prvEvalTick;
214 residencies[_currState] += elapsed_time;
215
216 ret.resize(enums::PwrState::Num_PwrState);
217 for (unsigned i = 0; i < enums::PwrState::Num_PwrState; i++)
218 ret[i] = residencies[i] / \
219 (stats.pwrStateResidencyTicks.total() + elapsed_time);
220
221 return ret;
222}
223
225 : statistics::Group(&co),
226 powerState(co),
227 ADD_STAT(numTransitions, statistics::units::Count::get(),
228 "Number of power state transitions"),
229 ADD_STAT(numPwrMatchStateTransitions, statistics::units::Count::get(),
230 "Number of power state transitions due match request"),
231 ADD_STAT(ticksClkGated, statistics::units::Tick::get(),
232 "Distribution of time spent in the clock gated state"),
233 ADD_STAT(pwrStateResidencyTicks, statistics::units::Tick::get(),
234 "Cumulative time (in ticks) in various power states")
235{
236}
237
238void
240{
242
243 using namespace statistics;
244
245 const PowerStateParams &p = powerState.params();
246
247 numTransitions.flags(nozero);
248 numPwrMatchStateTransitions.flags(nozero);
249
250 // Each sample is time in ticks
251 unsigned num_bins = std::max(p.clk_gate_bins, 10U);
252 ticksClkGated
253 .init(p.clk_gate_min, p.clk_gate_max,
254 (p.clk_gate_max - p.clk_gate_min + 1.0) / num_bins)
255 .flags(pdf | nozero | nonan)
256 ;
257
258 pwrStateResidencyTicks
259 .init(enums::PwrState::Num_PwrState)
260 .flags(nozero)
261 ;
262 for (int i = 0; i < enums::PwrState::Num_PwrState; i++) {
263 pwrStateResidencyTicks.subname(i, enums::PwrStateStrings[i]);
264 }
265
266 numTransitions = 0;
267}
268
269void
271{
273
282 powerState.computeStats();
283}
284
285} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
virtual std::string name() const
Definition named.hh:47
The PowerDomain groups PowerState objects together to regulate their power states.
void pwrStateChangeCallback(enums::PwrState new_pwr_state, PowerState *leader)
Register the change in power state in one of the leader.
Helper class for objects that have power states.
void set(enums::PwrState p)
Change the power state of this object to the power state p.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
enums::PwrState _currState
To keep track of the current power state.
void computeStats()
Record stats values like state residency by computing the time difference from previous update.
gem5::PowerState::PowerStateStats stats
PowerState(const PowerStateParams &p)
std::vector< double > getWeights() const
Returns the percentage residency for each power state.
std::set< enums::PwrState > possibleStates
The possible power states this object can be in.
PowerDomain * controlledDomain
The power domain that this power state leads, nullptr if it doesn't lead any.
enums::PwrState matchPwrState(enums::PwrState p)
Change the power state of this object to a power state equal to OR more performant than p.
Tick prvEvalTick
Last tick the power stats were calculated.
void setControlledDomain(PowerDomain *pwr_dom)
void serialize(CheckpointOut &cp) const override
Serialize an object.
Abstract superclass for simulation objects.
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
Statistics container.
Definition group.hh:93
void value(VCounter &vec) const
Result total() const
Return a total of all entries in this vector.
STL vector class.
Definition stl.hh:37
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition group.hh:75
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition logging.hh:214
virtual void regStats()
Callback to set stat parameters.
Definition group.cc:68
virtual void preDumpStats()
Callback before stats are dumped.
Definition group.cc:99
#define warn(...)
Definition logging.hh:256
#define warn_once(...)
Definition logging.hh:260
#define warn_if(cond,...)
Conditional warning macro that checks the supplied condition and only prints a warning if the conditi...
Definition logging.hh:283
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 12, 11 > set
Bitfield< 0 > p
const FlagsType pdf
Print the percent of the total that this entry represents.
Definition info.hh:61
const FlagsType nonan
Don't print if this is NAN.
Definition info.hh:69
const FlagsType nozero
Don't print if this is zero.
Definition info.hh:67
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
Tick curTick()
The universal simulation clock.
Definition cur_tick.hh:46
std::ostream CheckpointOut
Definition serialize.hh:66
uint64_t Tick
Tick count type.
Definition types.hh:58
PowerState declaration and implementation.
#define UNSERIALIZE_SCALAR(scalar)
Definition serialize.hh:575
#define SERIALIZE_SCALAR(scalar)
Definition serialize.hh:568
statistics::Distribution ticksClkGated
statistics::Vector pwrStateResidencyTicks
Tracks the time spent in each of the power states.
void regStats() override
Callback to set stat parameters.
void preDumpStats() override
Callback before stats are dumped.
statistics::Scalar numPwrMatchStateTransitions

Generated on Tue Jun 18 2024 16:24:06 for gem5 by doxygen 1.11.0