gem5  v20.1.0.0
dvfs_handler.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-2014 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/dvfs_handler.hh"
39 
40 #include <set>
41 #include <utility>
42 
43 #include "base/logging.hh"
44 #include "base/trace.hh"
45 #include "debug/DVFS.hh"
46 #include "params/DVFSHandler.hh"
47 #include "sim/clock_domain.hh"
48 #include "sim/eventq.hh"
49 #include "sim/stat_control.hh"
50 #include "sim/voltage_domain.hh"
51 
52 //
53 //
54 // DVFSHandler methods implementation
55 //
56 
58  : SimObject(p),
59  sysClkDomain(p->sys_clk_domain),
60  enableHandler(p->enable),
61  _transLatency(p->transition_latency)
62 {
63  // Check supplied list of domains for sanity and add them to the
64  // domain ID -> domain* hash
65  for (auto dit = p->domains.begin(); dit != p->domains.end(); ++dit) {
66  SrcClockDomain *d = *dit;
67  DomainID domain_id = d->domainID();
68 
69  fatal_if(sysClkDomain == d, "DVFS: Domain config list has a "\
70  "system clk domain entry");
72  "DVFS: Controlled domain %s needs to have a properly "\
73  " assigned ID.\n", d->name());
74 
75  auto entry = std::make_pair(domain_id, d);
76  bool new_elem = domains.insert(entry).second;
77  fatal_if(!new_elem, "DVFS: Domain %s with ID %d does not have a "\
78  "unique ID.\n", d->name(), domain_id);
79 
80  // Create a dedicated event slot per known domain ID
81  UpdateEvent *event = &updatePerfLevelEvents[domain_id];
82  event->domainIDToSet = d->domainID();
83 
84  // Add domain ID to the list of domains
85  domainIDList.push_back(d->domainID());
86  }
88 }
89 
91 
94 {
95  fatal_if(index >= numDomains(), "DVFS: Requested index out of "\
96  "bound, max value %d\n", (domainIDList.size() - 1));
97 
98  assert(domains.find(domainIDList[index]) != domains.end());
99 
100  return domainIDList[index];
101 }
102 
103 bool
105 {
106  assert(isEnabled());
107  // This is ensure that the domain id as requested by the software is
108  // availabe in the handler.
109  if (domains.find(domain_id) != domains.end())
110  return true;
111  warn("DVFS: invalid domain ID %d, the DVFS handler does not handle this "\
112  "domain\n", domain_id);
113  return false;
114 }
115 
116 bool
118 {
119  assert(isEnabled());
120 
121  DPRINTF(DVFS, "DVFS: setPerfLevel domain %d -> %d\n", domain_id, perf_level);
122 
123  auto d = findDomain(domain_id);
124  if (!d->validPerfLevel(perf_level)) {
125  warn("DVFS: invalid performance level %d for domain ID %d, request "\
126  "ignored\n", perf_level, domain_id);
127  return false;
128  }
129 
130  UpdateEvent *update_event = &updatePerfLevelEvents[domain_id];
131  // Drop an old DVFS change request once we have established that this is a
132  // reasonable request
133  if (update_event->scheduled()) {
134  DPRINTF(DVFS, "DVFS: Overwriting the previous DVFS event.\n");
135  deschedule(update_event);
136  }
137 
138  update_event->perfLevelToSet = perf_level;
139 
140  // State changes that restore to the current state (and / or overwrite a not
141  // yet completed in-flight request) will be squashed
142  if (d->perfLevel() == perf_level) {
143  DPRINTF(DVFS, "DVFS: Ignoring ineffective performance level change "\
144  "%d -> %d\n", d->perfLevel(), perf_level);
145  return false;
146  }
147 
148  // At this point, a new transition will certainly take place -> schedule
149  Tick when = curTick() + _transLatency;
150  DPRINTF(DVFS, "DVFS: Update for perf event scheduled for %ld\n", when);
151 
152  schedule(update_event, when);
153  return true;
154 }
155 
156 void
158 {
159  // Perform explicit stats dump for power estimation before performance
160  // level migration
161  Stats::dump();
162  Stats::reset();
163 
164  // Update the performance level in the clock domain
166  assert(d->perfLevel() != perfLevelToSet);
167 
168  d->perfLevel(perfLevelToSet);
169 }
170 
171 double
173 {
174  VoltageDomain *d = findDomain(domain_id)->voltageDomain();
175  assert(d);
176  PerfLevel n = d->numVoltages();
177  if (perf_level < n)
178  return d->voltage(perf_level);
179 
180  // Request outside of the range of the voltage domain
181  if (n == 1) {
182  DPRINTF(DVFS, "DVFS: Request for perf-level %i for single-point "\
183  "voltage domain %s. Returning voltage at level 0: %.2f "\
184  "V\n", perf_level, d->name(), d->voltage(0));
185  // Special case for single point voltage domain -> same voltage for
186  // all points
187  return d->voltage(0);
188  }
189 
190  warn("DVFSHandler %s reads illegal voltage level %u from "\
191  "VoltageDomain %s. Returning 0 V\n", name(), perf_level, d->name());
192  return 0.;
193 }
194 
195 void
197 {
198  //This is to ensure that the handler status is maintained during the
199  //entire simulation run and not changed from command line during checkpoint
200  //and restore
202 
203  // Pull out the hashed data structure into easy-to-serialise arrays;
204  // ensuring that the data associated with any pending update event is saved
205  std::vector<DomainID> domain_ids;
206  std::vector<PerfLevel> perf_levels;
207  std::vector<Tick> whens;
208  for (const auto &ev_pair : updatePerfLevelEvents) {
209  DomainID id = ev_pair.first;
210  const UpdateEvent *event = &ev_pair.second;
211 
212  assert(id == event->domainIDToSet);
213  domain_ids.push_back(id);
214  perf_levels.push_back(event->perfLevelToSet);
215  whens.push_back(event->scheduled() ? event->when() : 0);
216  }
217  SERIALIZE_CONTAINER(domain_ids);
218  SERIALIZE_CONTAINER(perf_levels);
219  SERIALIZE_CONTAINER(whens);
220 }
221 
222 void
224 {
225  bool temp = enableHandler;
226 
228 
229  if (temp != enableHandler) {
230  warn("DVFS: Forcing enable handler status to unserialized value of %d",
231  enableHandler);
232  }
233 
234  // Reconstruct the map of domain IDs and their scheduled events
235  std::vector<DomainID> domain_ids;
236  std::vector<PerfLevel> perf_levels;
237  std::vector<Tick> whens;
238  UNSERIALIZE_CONTAINER(domain_ids);
239  UNSERIALIZE_CONTAINER(perf_levels);
240  UNSERIALIZE_CONTAINER(whens);
241 
242  for (size_t i = 0; i < domain_ids.size(); ++i) {;
243  UpdateEvent *event = &updatePerfLevelEvents[domain_ids[i]];
244 
245  event->domainIDToSet = domain_ids[i];
246  event->perfLevelToSet = perf_levels[i];
247 
248  // Schedule all previously scheduled events
249  if (whens[i])
250  schedule(event, whens[i]);
251  }
253 }
254 
256 DVFSHandlerParams::create()
257 {
258  return new DVFSHandler(this);
259 }
DVFSHandler::Params
DVFSHandlerParams Params
Definition: dvfs_handler.hh:70
Event::scheduled
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:460
DVFSHandler::UpdateEvent
Update performance level event, encapsulates all the required information for a future call to change...
Definition: dvfs_handler.hh:222
warn
#define warn(...)
Definition: logging.hh:239
voltage_domain.hh
DVFSHandler::sysClkDomain
SrcClockDomain * sysClkDomain
Clock domain of the system the handler is instantiated.
Definition: dvfs_handler.hh:188
MipsISA::index
Bitfield< 30, 0 > index
Definition: pra_constants.hh:44
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:797
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
UNSERIALIZE_CONTAINER
#define UNSERIALIZE_CONTAINER(member)
Definition: serialize.hh:856
DVFSHandler::findDomain
SrcClockDomain * findDomain(DomainID domain_id) const
Search for a domain based on the domain ID.
Definition: dvfs_handler.hh:196
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:63
SrcClockDomain
The source clock domains provides the notion of a clock domain that is connected to a tunable clock s...
Definition: clock_domain.hh:163
DVFSHandler::voltageAtPerfLevel
double voltageAtPerfLevel(DomainID domain_id, PerfLevel perf_level) const
Read the voltage of the specified domain at the specified performance level.
Definition: dvfs_handler.cc:172
EventManager::deschedule
void deschedule(Event &event)
Definition: eventq.hh:1014
std::vector< DomainID >
SrcClockDomain::emptyDomainID
static const DomainID emptyDomainID
Definition: clock_domain.hh:181
DVFSHandler::validDomainID
bool validDomainID(DomainID domain_id) const
Check whether a domain ID is known to the handler or not.
Definition: dvfs_handler.cc:104
DVFSHandler::updatePerfLevelEvents
UpdatePerfLevelEvents updatePerfLevelEvents
Map from domain IDs -> perf level update events, records in-flight change requests per domain ID.
Definition: dvfs_handler.hh:257
Stats::reset
void reset()
Definition: statistics.cc:569
DVFSHandler::isEnabled
bool isEnabled() const
Check enable status of the DVFS handler, when the handler is disabled, no request should be sent to t...
Definition: dvfs_handler.hh:171
DVFSHandler::UpdateEvent::dvfsHandler
static DVFSHandler * dvfsHandler
Static pointer to the single DVFS hander for all the update events.
Definition: dvfs_handler.hh:229
DVFSHandler::enableHandler
bool enableHandler
Disabling the DVFS handler ensures that all the DVFS migration requests are ignored.
Definition: dvfs_handler.hh:207
DVFSHandler::domains
Domains domains
Definition: dvfs_handler.hh:178
ArmISA::n
Bitfield< 31 > n
Definition: miscregs_types.hh:450
ArmISA::dit
Bitfield< 51, 48 > dit
Definition: miscregs_types.hh:165
cp
Definition: cprintf.cc:40
EventManager::schedule
void schedule(Event &event, Tick when)
Definition: eventq.hh:1005
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
DVFSHandler::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: dvfs_handler.cc:223
DVFSHandler::UpdateEvent::domainIDToSet
DomainID domainIDToSet
ID of the domain that will be changed by the in-flight event.
Definition: dvfs_handler.hh:234
ArmISA::d
Bitfield< 9 > d
Definition: miscregs_types.hh:60
DVFSHandler::UpdateEvent::perfLevelToSet
PerfLevel perfLevelToSet
Target performance level of the in-flight event.
Definition: dvfs_handler.hh:239
MipsISA::event
Bitfield< 10, 5 > event
Definition: pra_constants.hh:297
DVFSHandler::numDomains
uint32_t numDomains() const
Get the number of domains assigned to this DVFS handler.
Definition: dvfs_handler.hh:80
DVFSHandler::domainID
DomainID domainID(uint32_t index) const
Get the n-th domain ID, from the domains managed by this handler.
Definition: dvfs_handler.cc:93
VoltageDomain
A VoltageDomain is used to group clock domains that operate under the same voltage.
Definition: voltage_domain.hh:53
DVFSHandler::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: dvfs_handler.cc:196
DVFSHandler::domainIDList
std::vector< DomainID > domainIDList
List of IDs avaiable in the domain list.
Definition: dvfs_handler.hh:183
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:790
ClockDomain::voltageDomain
VoltageDomain * voltageDomain() const
Get the voltage domain.
Definition: clock_domain.hh:124
clock_domain.hh
SimObject::name
virtual const std::string name() const
Definition: sim_object.hh:133
stat_control.hh
dvfs_handler.hh
X86ISA::enable
Bitfield< 11 > enable
Definition: misc.hh:1051
Stats::dump
void dump()
Dump all statistics data to the registered outputs.
Definition: statistics.cc:560
SERIALIZE_CONTAINER
#define SERIALIZE_CONTAINER(member)
Definition: serialize.hh:848
logging.hh
DVFSHandler::DomainID
SrcClockDomain::DomainID DomainID
Definition: dvfs_handler.hh:73
CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:63
trace.hh
DVFSHandler::_transLatency
const Tick _transLatency
This corresponds to the maximum transition latency associated with the hardware transitioning from a ...
Definition: dvfs_handler.hh:214
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
DVFSHandler::PerfLevel
SrcClockDomain::PerfLevel PerfLevel
Definition: dvfs_handler.hh:74
DVFSHandler::DVFSHandler
DVFSHandler(const Params *p)
Definition: dvfs_handler.cc:57
DVFSHandler::UpdateEvent::updatePerfLevel
void updatePerfLevel()
Updates the performance level by modifying the clock and the voltage of the associated clocked object...
Definition: dvfs_handler.cc:157
fatal_if
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:219
CheckpointIn
Definition: serialize.hh:67
DVFSHandler::perfLevel
bool perfLevel(DomainID domain_id, PerfLevel perf_level)
Set a new performance level for the specified domain.
Definition: dvfs_handler.cc:117
DVFSHandler
DVFS Handler class, maintains a list of all the domains it can handle.
Definition: dvfs_handler.hh:67
curTick
Tick curTick()
The current simulated tick.
Definition: core.hh:45
eventq.hh
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