gem5  v20.1.0.0
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 "base/logging.hh"
41 #include "base/trace.hh"
42 #include "debug/PowerDomain.hh"
43 #include "sim/power_domain.hh"
44 
45 PowerState::PowerState(const PowerStateParams *p) :
46  SimObject(p), _currState(p->default_state),
47  possibleStates(p->possible_states.begin(),
48  p->possible_states.end()),
49  stats(*this)
50 {
51  for (auto &pm: p->leaders) {
52  // Register this object as a follower. This object is
53  // dependent on pm for power state transitions
54  pm->addFollower(this);
55  }
56 }
57 
58 void
60 {
61  // Only a power domain can register as dependant of a power stated
62  // object
63  controlledDomain = pwr_dom;
64  DPRINTF(PowerDomain, "%s is registered as controlled by %s \n",
65  pwr_dom->name(), name());
66 }
67 
68 void
70 {
71  unsigned int currState = (unsigned int)_currState;
72 
73  SERIALIZE_SCALAR(currState);
75 }
76 
77 void
79 {
80  unsigned int currState;
81 
82  UNSERIALIZE_SCALAR(currState);
84 
85  _currState = Enums::PwrState(currState);
86 }
87 
88 void
89 PowerState::set(Enums::PwrState p)
90 {
91  // Check if this power state is actually allowed by checking whether it is
92  // present in pwrStateToIndex-dictionary
93  panic_if(possibleStates.find(p) == possibleStates.end(),
94  "Cannot go to %s in %s \n", Enums::PwrStateStrings[p], name());
95 
96  // Function should ideally be called only when there is a state change
97  if (_currState == p) {
98  warn_once("PowerState: Already in the requested power state, "
99  "request ignored");
100  return;
101  }
102 
103  // No need to compute stats if in the same tick, update state though. This
104  // can happen in cases like a) during start of the simulation multiple
105  // state changes happens in init/startup phase, b) one takes a decision to
106  // migrate state but decides to reverts back to the original state in the
107  // same tick if other conditions are not met elsewhere.
108  // Any state change related stats would have been recorded on previous call
109  // to this function.
110  if (prvEvalTick == curTick() && curTick() != 0) {
111  warn("PowerState: More than one power state change request "
112  "encountered within the same simulation tick");
113  _currState = p;
114  return;
115  }
116 
117  // Record stats for previous state.
118  computeStats();
119 
120  _currState = p;
121 
123 
124  // Update the domain this object controls, if there is one
125  if (controlledDomain) {
127  }
128 
129 }
130 
131 Enums::PwrState
132 PowerState::matchPwrState(Enums::PwrState p)
133 {
134  // If the object is asked to match a power state, it has to be a follower
135  // and hence should not have a pointer to a powerDomain
136  assert(controlledDomain == nullptr);
137 
138  // If we are already in this power state, ignore request
139  if (_currState == p) {
140  DPRINTF(PowerDomain, "Already in p-state %s requested to match \n",
141  Enums::PwrStateStrings[p]);
142  return _currState;
143  }
144 
145  Enums::PwrState old_state = _currState;
146  if (possibleStates.find(p) != possibleStates.end()) {
147  // If this power state is allowed in this object, just go there
148  set(p);
149  } else {
150  // Loop over all power states in this object and find a power state
151  // which is more performant than the requested one (considering we
152  // cannot match it exactly)
153  for (auto rev_it = possibleStates.crbegin();
154  rev_it != possibleStates.crend(); rev_it++) {
155  if (*(rev_it) <= p) {
156  // This power state is the least performant power state that is
157  // still more performant than the requested one
158  DPRINTF(PowerDomain, "Best match for %s is %s \n",
159  Enums::PwrStateStrings[p],
160  Enums::PwrStateStrings[*(rev_it)]);
161  set(*(rev_it));
162  break;
163  }
164  }
165  }
166  // Check if the transition happened
167  // The only case in which the power state cannot change is if the
168  // object is already at in its most performant state.
169  warn_if((_currState == old_state) &&
170  possibleStates.find(_currState) != possibleStates.begin(),
171  "Transition to power state %s was not possible, SimObject already"
172  " in the most performance state %s",
173  Enums::PwrStateStrings[p], Enums::PwrStateStrings[_currState]);
174 
176  return _currState;
177 }
178 
179 void
181 {
182  // Calculate time elapsed from last (valid) state change
183  Tick elapsed_time = curTick() - prvEvalTick;
184 
185  stats.pwrStateResidencyTicks[_currState] += elapsed_time;
186 
187  // Time spent in CLK_GATED state, this might change depending on
188  // transition to other low power states in respective simulation
189  // objects.
190  if (_currState == Enums::PwrState::CLK_GATED) {
191  stats.ticksClkGated.sample(elapsed_time);
192  }
193 
194  prvEvalTick = curTick();
195 }
196 
199 {
200  // Get residency stats
202  Stats::VCounter residencies;
203  stats.pwrStateResidencyTicks.value(residencies);
204 
205  // Account for current state too!
206  Tick elapsed_time = curTick() - prvEvalTick;
207  residencies[_currState] += elapsed_time;
208 
209  ret.resize(Enums::PwrState::Num_PwrState);
210  for (unsigned i = 0; i < Enums::PwrState::Num_PwrState; i++)
211  ret[i] = residencies[i] / \
212  (stats.pwrStateResidencyTicks.total() + elapsed_time);
213 
214  return ret;
215 }
216 
218  : Stats::Group(&co),
219  powerState(co),
220  ADD_STAT(numTransitions,
221  "Number of power state transitions"),
222  ADD_STAT(numPwrMatchStateTransitions,
223  "Number of power state transitions due match request"),
224  ADD_STAT(ticksClkGated,
225  "Distribution of time spent in the clock gated state"),
226  ADD_STAT(pwrStateResidencyTicks,
227  "Cumulative time (in ticks) in various power states")
228 {
229 }
230 
231 void
233 {
235 
236  using namespace Stats;
237 
238  const PowerStateParams *p = powerState.params();
239 
240  numTransitions.flags(nozero);
241  numPwrMatchStateTransitions.flags(nozero);
242 
243  // Each sample is time in ticks
244  unsigned num_bins = std::max(p->clk_gate_bins, 10U);
245  ticksClkGated
246  .init(p->clk_gate_min, p->clk_gate_max,
247  (p->clk_gate_max / num_bins))
248  .flags(pdf | nozero | nonan)
249  ;
250 
251  pwrStateResidencyTicks
252  .init(Enums::PwrState::Num_PwrState)
253  .flags(nozero)
254  ;
255  for (int i = 0; i < Enums::PwrState::Num_PwrState; i++) {
256  pwrStateResidencyTicks.subname(i, Enums::PwrStateStrings[i]);
257  }
258 
259  numTransitions = 0;
260 }
261 
262 void
264 {
266 
275  powerState.computeStats();
276 }
277 
278 PowerState*
279 PowerStateParams::create()
280 {
281  return new PowerState(this);
282 }
Stats::Group::regStats
virtual void regStats()
Callback to set stat parameters.
Definition: group.cc:64
power_state.hh
PowerState::possibleStates
std::set< Enums::PwrState > possibleStates
The possible power states this object can be in.
Definition: power_state.hh:126
PowerState::PowerStateStats::preDumpStats
void preDumpStats() override
Callback before stats are dumped.
Definition: power_state.cc:263
warn
#define warn(...)
Definition: logging.hh:239
PowerState::matchPwrState
Enums::PwrState matchPwrState(Enums::PwrState p)
Change the power state of this object to a power state equal to OR more performant than p.
Definition: power_state.cc:132
PowerState::prvEvalTick
Tick prvEvalTick
Last tick the power stats were calculated.
Definition: power_state.hh:129
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:797
PowerState::set
void set(Enums::PwrState p)
Change the power state of this object to the power state p.
Definition: power_state.cc:89
warn_once
#define warn_once(...)
Definition: logging.hh:243
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
PowerState::controlledDomain
PowerDomain * controlledDomain
The power domain that this power state leads, nullptr if it doesn't lead any.
Definition: power_state.hh:135
PowerDomain
The PowerDomain groups PowerState objects together to regulate their power states.
Definition: power_domain.hh:56
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:63
Stats::Group::preDumpStats
virtual void preDumpStats()
Callback before stats are dumped.
Definition: group.cc:95
std::vector< double >
PowerState::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: power_state.cc:69
power_domain.hh
PowerState::PowerStateStats::pwrStateResidencyTicks
Stats::Vector pwrStateResidencyTicks
Tracks the time spent in each of the power states.
Definition: power_state.hh:150
PowerState::PowerStateStats::numPwrMatchStateTransitions
Stats::Scalar numPwrMatchStateTransitions
Definition: power_state.hh:147
PowerState::getWeights
std::vector< double > getWeights() const
Returns the percentage residency for each power state.
Definition: power_state.cc:198
cp
Definition: cprintf.cc:40
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
ADD_STAT
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:67
PowerState::stats
PowerState::PowerStateStats stats
PowerState
Helper class for objects that have power states.
Definition: power_state.hh:61
PowerDomain::pwrStateChangeCallback
void pwrStateChangeCallback(Enums::PwrState new_pwr_state, PowerState *leader)
Register the change in power state in one of the leader.
Definition: power_domain.cc:211
PowerState::_currState
Enums::PwrState _currState
To keep track of the current power state.
Definition: power_state.hh:123
PowerState::PowerStateStats::regStats
void regStats() override
Callback to set stat parameters.
Definition: power_state.cc:232
PowerState::PowerStateStats::PowerStateStats
PowerStateStats(PowerState &ps)
Definition: power_state.cc:217
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:790
PowerState::PowerState
PowerState(const PowerStateParams *p)
Definition: power_state.cc:45
Stats::nozero
const FlagsType nozero
Don't print if this is zero.
Definition: info.hh:57
SimObject::name
virtual const std::string name() const
Definition: sim_object.hh:133
warn_if
#define warn_if(cond,...)
Conditional warning macro that checks the supplied condition and only prints a warning if the conditi...
Definition: logging.hh:263
panic_if
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:197
Stats::pdf
const FlagsType pdf
Print the percent of the total that this entry represents.
Definition: info.hh:51
PowerState::PowerStateStats::numTransitions
Stats::Scalar numTransitions
Definition: power_state.hh:146
Stats::DistBase::sample
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
Definition: statistics.hh:1924
logging.hh
PowerState::computeStats
void computeStats()
Record stats values like state residency by computing the time difference from previous update.
Definition: power_state.cc:180
CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:63
Stats
Definition: statistics.cc:61
trace.hh
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
PowerState::PowerStateStats::ticksClkGated
Stats::Distribution ticksClkGated
Definition: power_state.hh:148
CheckpointIn
Definition: serialize.hh:67
Stats::VectorBase::value
void value(VCounter &vec) const
Definition: statistics.hh:1103
PowerState::setControlledDomain
void setControlledDomain(PowerDomain *pwr_dom)
Definition: power_state.cc:59
Stats::VectorBase::total
Result total() const
Return a total of all entries in this vector.
Definition: statistics.hh:1127
Stats::nonan
const FlagsType nonan
Don't print if this is NAN.
Definition: info.hh:59
PowerState::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: power_state.cc:78
curTick
Tick curTick()
The current simulated tick.
Definition: core.hh:45
SimObject
Abstract superclass for simulation objects.
Definition: sim_object.hh:92

Generated on Wed Sep 30 2020 14:02:14 for gem5 by doxygen 1.8.17