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

Generated on Sun Jul 30 2023 01:56:59 for gem5 by doxygen 1.8.17