gem5  v21.0.1.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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/trace.hh"
44 #include "debug/DVFS.hh"
45 #include "params/DVFSHandler.hh"
46 #include "sim/serialize.hh"
47 #include "sim/stat_control.hh"
48 #include "sim/voltage_domain.hh"
49 
50 //
51 //
52 // DVFSHandler methods implementation
53 //
54 
56  : SimObject(p),
57  sysClkDomain(p.sys_clk_domain),
58  enableHandler(p.enable),
59  _transLatency(p.transition_latency)
60 {
61  // Check supplied list of domains for sanity and add them to the
62  // domain ID -> domain* hash
63  for (auto dit = p.domains.begin(); dit != p.domains.end(); ++dit) {
64  SrcClockDomain *d = *dit;
65  DomainID domain_id = d->domainID();
66 
67  fatal_if(sysClkDomain == d, "DVFS: Domain config list has a "\
68  "system clk domain entry");
70  "DVFS: Controlled domain %s needs to have a properly "\
71  " assigned ID.\n", d->name());
72 
73  auto entry = std::make_pair(domain_id, d);
74  bool new_elem = domains.insert(entry).second;
75  fatal_if(!new_elem, "DVFS: Domain %s with ID %d does not have a "\
76  "unique ID.\n", d->name(), domain_id);
77 
78  // Create a dedicated event slot per known domain ID
79  UpdateEvent *event = &updatePerfLevelEvents[domain_id];
80  event->domainIDToSet = d->domainID();
81 
82  // Add domain ID to the list of domains
83  domainIDList.push_back(d->domainID());
84  }
86 }
87 
89 
92 {
93  fatal_if(index >= numDomains(), "DVFS: Requested index out of "\
94  "bound, max value %d\n", (domainIDList.size() - 1));
95 
96  assert(domains.find(domainIDList[index]) != domains.end());
97 
98  return domainIDList[index];
99 }
100 
101 bool
103 {
104  assert(isEnabled());
105  // This is ensure that the domain id as requested by the software is
106  // availabe in the handler.
107  if (domains.find(domain_id) != domains.end())
108  return true;
109  warn("DVFS: invalid domain ID %d, the DVFS handler does not handle this "\
110  "domain\n", domain_id);
111  return false;
112 }
113 
114 bool
116 {
117  assert(isEnabled());
118 
119  DPRINTF(DVFS, "DVFS: setPerfLevel domain %d -> %d\n", domain_id, perf_level);
120 
121  auto d = findDomain(domain_id);
122  if (!d->validPerfLevel(perf_level)) {
123  warn("DVFS: invalid performance level %d for domain ID %d, request "\
124  "ignored\n", perf_level, domain_id);
125  return false;
126  }
127 
128  UpdateEvent *update_event = &updatePerfLevelEvents[domain_id];
129  // Drop an old DVFS change request once we have established that this is a
130  // reasonable request
131  if (update_event->scheduled()) {
132  DPRINTF(DVFS, "DVFS: Overwriting the previous DVFS event.\n");
133  deschedule(update_event);
134  }
135 
136  update_event->perfLevelToSet = perf_level;
137 
138  // State changes that restore to the current state (and / or overwrite a not
139  // yet completed in-flight request) will be squashed
140  if (d->perfLevel() == perf_level) {
141  DPRINTF(DVFS, "DVFS: Ignoring ineffective performance level change "\
142  "%d -> %d\n", d->perfLevel(), perf_level);
143  return false;
144  }
145 
146  // At this point, a new transition will certainly take place -> schedule
147  Tick when = curTick() + _transLatency;
148  DPRINTF(DVFS, "DVFS: Update for perf event scheduled for %ld\n", when);
149 
150  schedule(update_event, when);
151  return true;
152 }
153 
154 void
156 {
157  // Perform explicit stats dump for power estimation before performance
158  // level migration
159  Stats::dump();
160  Stats::reset();
161 
162  // Update the performance level in the clock domain
164  assert(d->perfLevel() != perfLevelToSet);
165 
166  d->perfLevel(perfLevelToSet);
167 }
168 
169 double
171 {
172  VoltageDomain *d = findDomain(domain_id)->voltageDomain();
173  assert(d);
174  PerfLevel n = d->numVoltages();
175  if (perf_level < n)
176  return d->voltage(perf_level);
177 
178  // Request outside of the range of the voltage domain
179  if (n == 1) {
180  DPRINTF(DVFS, "DVFS: Request for perf-level %i for single-point "\
181  "voltage domain %s. Returning voltage at level 0: %.2f "\
182  "V\n", perf_level, d->name(), d->voltage(0));
183  // Special case for single point voltage domain -> same voltage for
184  // all points
185  return d->voltage(0);
186  }
187 
188  warn("DVFSHandler %s reads illegal voltage level %u from "\
189  "VoltageDomain %s. Returning 0 V\n", name(), perf_level, d->name());
190  return 0.;
191 }
192 
193 void
195 {
196  //This is to ensure that the handler status is maintained during the
197  //entire simulation run and not changed from command line during checkpoint
198  //and restore
200 
201  // Pull out the hashed data structure into easy-to-serialise arrays;
202  // ensuring that the data associated with any pending update event is saved
203  std::vector<DomainID> domain_ids;
204  std::vector<PerfLevel> perf_levels;
205  std::vector<Tick> whens;
206  for (const auto &ev_pair : updatePerfLevelEvents) {
207  DomainID id = ev_pair.first;
208  const UpdateEvent *event = &ev_pair.second;
209 
210  assert(id == event->domainIDToSet);
211  domain_ids.push_back(id);
212  perf_levels.push_back(event->perfLevelToSet);
213  whens.push_back(event->scheduled() ? event->when() : 0);
214  }
215  SERIALIZE_CONTAINER(domain_ids);
216  SERIALIZE_CONTAINER(perf_levels);
217  SERIALIZE_CONTAINER(whens);
218 }
219 
220 void
222 {
223  bool temp = enableHandler;
224 
226 
227  if (temp != enableHandler) {
228  warn("DVFS: Forcing enable handler status to unserialized value of %d",
229  enableHandler);
230  }
231 
232  // Reconstruct the map of domain IDs and their scheduled events
233  std::vector<DomainID> domain_ids;
234  std::vector<PerfLevel> perf_levels;
235  std::vector<Tick> whens;
236  UNSERIALIZE_CONTAINER(domain_ids);
237  UNSERIALIZE_CONTAINER(perf_levels);
238  UNSERIALIZE_CONTAINER(whens);
239 
240  for (size_t i = 0; i < domain_ids.size(); ++i) {;
241  UpdateEvent *event = &updatePerfLevelEvents[domain_ids[i]];
242 
243  event->domainIDToSet = domain_ids[i];
244  event->perfLevelToSet = perf_levels[i];
245 
246  // Schedule all previously scheduled events
247  if (whens[i])
248  schedule(event, whens[i]);
249  }
251 }
DVFSHandler::Params
DVFSHandlerParams Params
Definition: dvfs_handler.hh:74
Event::scheduled
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:462
DVFSHandler::UpdateEvent
Update performance level event, encapsulates all the required information for a future call to change...
Definition: dvfs_handler.hh:226
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:192
MipsISA::index
Bitfield< 30, 0 > index
Definition: pra_constants.hh:44
serialize.hh
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:591
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
UNSERIALIZE_CONTAINER
#define UNSERIALIZE_CONTAINER(member)
Definition: serialize.hh:650
DVFSHandler::findDomain
SrcClockDomain * findDomain(DomainID domain_id) const
Search for a domain based on the domain ID.
Definition: dvfs_handler.hh:200
DVFSHandler::DVFSHandler
DVFSHandler(const Params &p)
Definition: dvfs_handler.cc:55
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:59
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:170
EventManager::deschedule
void deschedule(Event &event)
Definition: eventq.hh:1025
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:102
DVFSHandler::updatePerfLevelEvents
UpdatePerfLevelEvents updatePerfLevelEvents
Map from domain IDs -> perf level update events, records in-flight change requests per domain ID.
Definition: dvfs_handler.hh:261
Stats::reset
void reset()
Definition: statistics.cc:299
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:175
DVFSHandler::UpdateEvent::dvfsHandler
static DVFSHandler * dvfsHandler
Static pointer to the single DVFS hander for all the update events.
Definition: dvfs_handler.hh:233
DVFSHandler::enableHandler
bool enableHandler
Disabling the DVFS handler ensures that all the DVFS migration requests are ignored.
Definition: dvfs_handler.hh:211
DVFSHandler::domains
Domains domains
Definition: dvfs_handler.hh:182
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:37
EventManager::schedule
void schedule(Event &event, Tick when)
Definition: eventq.hh:1016
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:237
DVFSHandler::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: dvfs_handler.cc:221
DVFSHandler::UpdateEvent::domainIDToSet
DomainID domainIDToSet
ID of the domain that will be changed by the in-flight event.
Definition: dvfs_handler.hh:238
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:243
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:84
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:91
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:194
DVFSHandler::domainIDList
std::vector< DomainID > domainIDList
List of IDs avaiable in the domain list.
Definition: dvfs_handler.hh:187
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:584
ClockDomain::voltageDomain
VoltageDomain * voltageDomain() const
Get the voltage domain.
Definition: clock_domain.hh:124
SimObject::name
virtual const std::string name() const
Definition: sim_object.hh:182
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:290
SERIALIZE_CONTAINER
#define SERIALIZE_CONTAINER(member)
Definition: serialize.hh:642
DVFSHandler::DomainID
SrcClockDomain::DomainID DomainID
Definition: dvfs_handler.hh:77
CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:64
curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:43
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:218
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
DVFSHandler::PerfLevel
SrcClockDomain::PerfLevel PerfLevel
Definition: dvfs_handler.hh:78
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:155
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:68
DVFSHandler::perfLevel
bool perfLevel(DomainID domain_id, PerfLevel perf_level)
Set a new performance level for the specified domain.
Definition: dvfs_handler.cc:115
DVFSHandler
DVFS Handler class, maintains a list of all the domains it can handle.
Definition: dvfs_handler.hh:71
SimObject
Abstract superclass for simulation objects.
Definition: sim_object.hh:141

Generated on Tue Jun 22 2021 15:28:30 for gem5 by doxygen 1.8.17