gem5 v24.0.0.0
Loading...
Searching...
No Matches
traffic_gen.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012-2013, 2016-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 */
38
39#include <libgen.h>
40#include <unistd.h>
41
42#include <cmath>
43#include <fstream>
44#include <sstream>
45
46#include "base/intmath.hh"
47#include "base/random.hh"
48#include "debug/TrafficGen.hh"
49#include "params/TrafficGen.hh"
50#include "sim/stats.hh"
51#include "sim/system.hh"
52
53namespace gem5
54{
55
56TrafficGen::TrafficGen(const TrafficGenParams &p)
58 configFile(p.config_file),
59 currState(0)
60{
61}
62
63void
70
71void
73{
75
76 // when not restoring from a checkpoint, make sure we kick things off
77 if (system->isTimingMode()) {
78 DPRINTF(TrafficGen, "Timing mode, activating request generator\n");
79 start();
80 } else {
82 "Traffic generator is only active in timing mode\n");
83 }
84}
85
86void
93
94void
96{
97 // @todo In the case of a stateful generator state such as the
98 // trace player we would also have to restore the position in the
99 // trace playback and the tick offset
101
103}
104
105std::string
106TrafficGen::resolveFile(const std::string &name)
107{
108 // Do nothing for empty and absolute file names
109 if (name.empty() || name[0] == '/')
110 return name;
111
112 char *config_path = strdup(configFile.c_str());
113 char *config_dir = dirname(config_path);
114 const std::string config_rel = csprintf("%s/%s", config_dir, name);
115 free(config_path);
116
117 // Check the path relative to the config file first
118 if (access(config_rel.c_str(), R_OK) == 0)
119 return config_rel;
120
121 // Fall back to the old behavior and search relative to the
122 // current working directory.
123 return name;
124}
125
126void
128{
129 // keep track of the transitions parsed to create the matrix when
130 // done
131 std::vector<Transition> transitions;
132
133 // open input file
134 std::ifstream infile;
135 infile.open(configFile.c_str(), std::ifstream::in);
136 if (!infile.is_open()) {
137 fatal("Traffic generator %s config file not found at %s\n",
138 name(), configFile);
139 }
140
141 bool init_state_set = false;
142
143 // read line by line and determine the action based on the first
144 // keyword
145 std::string keyword;
146 std::string line;
147
148 while (getline(infile, line).good()) {
149 // see if this line is a comment line, and if so skip it
150 if (line.find('#') != 1) {
151 // create an input stream for the tokenization
152 std::istringstream is(line);
153
154 // determine the keyword
155 is >> keyword;
156
157 if (keyword == "STATE") {
158 // parse the behaviour of this state
159 uint32_t id;
160 Tick duration;
161 std::string mode;
162
163 is >> id >> duration >> mode;
164
165 if (mode == "TRACE") {
166 std::string traceFile;
167 Addr addrOffset;
168
169 is >> traceFile >> addrOffset;
170 traceFile = resolveFile(traceFile);
171
172 states[id] = createTrace(duration, traceFile, addrOffset);
173 DPRINTF(TrafficGen, "State: %d TraceGen\n", id);
174 } else if (mode == "IDLE") {
175 states[id] = createIdle(duration);
176 DPRINTF(TrafficGen, "State: %d IdleGen\n", id);
177 } else if (mode == "EXIT") {
178 states[id] = createExit(duration);
179 DPRINTF(TrafficGen, "State: %d ExitGen\n", id);
180 } else if (mode == "LINEAR" || mode == "RANDOM" ||
181 mode == "DRAM" || mode == "DRAM_ROTATE" ||
182 mode == "NVM") {
183 uint32_t read_percent;
184 Addr start_addr;
185 Addr end_addr;
186 Addr blocksize;
187 Tick min_period;
188 Tick max_period;
189 Addr data_limit;
190
191 is >> read_percent >> start_addr >> end_addr >>
192 blocksize >> min_period >> max_period >> data_limit;
193
194 DPRINTF(TrafficGen, "%s, addr %x to %x, size %d,"
195 " period %d to %d, %d%% reads\n",
196 mode, start_addr, end_addr, blocksize, min_period,
197 max_period, read_percent);
198
199
200 if (mode == "LINEAR") {
201 states[id] = createLinear(duration, start_addr,
202 end_addr, blocksize,
203 min_period, max_period,
204 read_percent, data_limit);
205 DPRINTF(TrafficGen, "State: %d LinearGen\n", id);
206 } else if (mode == "RANDOM") {
207 states[id] = createRandom(duration, start_addr,
208 end_addr, blocksize,
209 min_period, max_period,
210 read_percent, data_limit);
211 DPRINTF(TrafficGen, "State: %d RandomGen\n", id);
212 } else if (mode == "DRAM" || mode == "DRAM_ROTATE" ||
213 mode == "NVM") {
214 // stride size (bytes) of the request for achieving
215 // required hit length
216 unsigned int stride_size;
217 unsigned int page_size;
218 unsigned int nbr_of_banks;
219 unsigned int nbr_of_banks_util;
220 unsigned _addr_mapping;
221 unsigned int nbr_of_ranks;
222
223 is >> stride_size >> page_size >> nbr_of_banks >>
224 nbr_of_banks_util >> _addr_mapping >>
225 nbr_of_ranks;
226 enums::AddrMap addr_mapping =
227 static_cast<enums::AddrMap>(_addr_mapping);
228
229 if (stride_size > page_size)
230 warn("Memory generator stride size (%d) is greater"
231 " than page size (%d) of the memory\n",
232 blocksize, page_size);
233
234 // count the number of sequential packets to
235 // generate
236 unsigned int num_seq_pkts = 1;
237
238 if (stride_size > blocksize) {
239 num_seq_pkts = divCeil(stride_size, blocksize);
240 DPRINTF(TrafficGen, "stride size: %d "
241 "block size: %d, num_seq_pkts: %d\n",
242 stride_size, blocksize, num_seq_pkts);
243 }
244
245 if (mode == "DRAM") {
246 states[id] = createDram(duration, start_addr,
247 end_addr, blocksize,
248 min_period, max_period,
249 read_percent, data_limit,
250 num_seq_pkts, page_size,
251 nbr_of_banks,
252 nbr_of_banks_util,
253 addr_mapping,
254 nbr_of_ranks);
255 DPRINTF(TrafficGen, "State: %d DramGen\n", id);
256 } else if (mode == "DRAM_ROTATE") {
257 // Will rotate to the next rank after rotating
258 // through all banks, for each command type.
259 // In the 50% read case, series will be issued
260 // for both RD & WR before the rank in incremented
261 unsigned int max_seq_count_per_rank =
262 (read_percent == 50) ? nbr_of_banks_util * 2
263 : nbr_of_banks_util;
264
265 states[id] = createDramRot(duration, start_addr,
266 end_addr, blocksize,
267 min_period, max_period,
268 read_percent,
269 data_limit,
270 num_seq_pkts, page_size,
271 nbr_of_banks,
272 nbr_of_banks_util,
273 addr_mapping,
274 nbr_of_ranks,
275 max_seq_count_per_rank);
276 DPRINTF(TrafficGen, "State: %d DramRotGen\n", id);
277 } else {
278 states[id] = createNvm(duration, start_addr,
279 end_addr, blocksize,
280 min_period, max_period,
281 read_percent, data_limit,
282 num_seq_pkts, page_size,
283 nbr_of_banks,
284 nbr_of_banks_util,
285 addr_mapping,
286 nbr_of_ranks);
287 DPRINTF(TrafficGen, "State: %d NvmGen\n", id);
288 }
289 }
290 } else if (mode == "STRIDED") {
291 uint32_t read_percent;
292 Addr start_addr;
293 Addr end_addr;
294 Addr offset;
295 Addr blocksize;
296 Addr superblock_size;
297 Addr stride_size;
298 Tick min_period;
299 Tick max_period;
300 Addr data_limit;
301
302 is >> read_percent >> start_addr >> end_addr >> offset >>
303 blocksize >> superblock_size >> stride_size >>
304 min_period >> max_period >> data_limit;
305
306 DPRINTF(TrafficGen, "%s, addr %x to %x with offset %x, "
307 "size %d, super size %d, stride size %d, "
308 "period %d to %d, %d%% reads\n",
309 mode, start_addr, end_addr, offset, blocksize,
310 superblock_size, stride_size, min_period,
311 max_period, read_percent);
312
314 duration, start_addr, end_addr, offset,
315 blocksize, superblock_size, stride_size,
316 min_period, max_period, read_percent, data_limit);
317
318 DPRINTF(TrafficGen, "State: %d StridedGen\n", id);
319 } else {
320 fatal("%s: Unknown traffic generator mode: %s",
321 name(), mode);
322 }
323 } else if (keyword == "TRANSITION") {
325
326 is >> transition.from >> transition.to >> transition.p;
327
328 transitions.push_back(transition);
329
330 DPRINTF(TrafficGen, "Transition: %d -> %d\n", transition.from,
331 transition.to);
332 } else if (keyword == "INIT") {
333 // set the initial state as the active state
334 is >> currState;
335
336 init_state_set = true;
337
338 DPRINTF(TrafficGen, "Initial state: %d\n", currState);
339 }
340 }
341 }
342
343 if (!init_state_set)
344 fatal("%s: initial state not specified (add 'INIT <id>' line "
345 "to the config file)\n", name());
346
347 // resize and populate state transition matrix
348 transitionMatrix.resize(states.size());
349 for (size_t i = 0; i < states.size(); i++) {
350 transitionMatrix[i].resize(states.size());
351 }
352
353 for (std::vector<Transition>::iterator t = transitions.begin();
354 t != transitions.end(); ++t) {
355 transitionMatrix[t->from][t->to] = t->p;
356 }
357
358 // ensure the egress edges do not have a probability larger than
359 // one
360 for (size_t i = 0; i < states.size(); i++) {
361 double sum = 0;
362 for (size_t j = 0; j < states.size(); j++) {
363 sum += transitionMatrix[i][j];
364 }
365
366 // avoid comparing floating point numbers
367 if (std::fabs(sum - 1.0) > 0.001) {
368 fatal("%s has transition probability != 1 for state %d\n",
369 name(), i);
370 }
371 }
372
373 // close input file
374 infile.close();
375}
376
377size_t
379{
380 double p = random_mt.random<double>();
381 assert(currState < transitionMatrix.size());
382 double cumulative = 0.0;
383 size_t i = 0;
384 do {
385 cumulative += transitionMatrix[currState][i];
386 ++i;
387 } while (cumulative < p && i < transitionMatrix[currState].size());
388
389 return i - 1;
390}
391
392std::shared_ptr<BaseGen>
394{
395 // Return the initial state if there isn't an active generator,
396 // otherwise perform a state transition.
397 if (activeGenerator)
399
400 DPRINTF(TrafficGen, "Transition to state %d\n", currState);
401 return states[currState];
402}
403
404} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
The traffic generator is a module that generates stimuli for the memory system, based on a collection...
Definition base.hh:68
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition base.cc:104
std::shared_ptr< BaseGen > createIdle(Tick duration)
Definition base.cc:370
std::shared_ptr< BaseGen > createLinear(Tick duration, Addr start_addr, Addr end_addr, Addr blocksize, Tick min_period, Tick max_period, uint8_t read_percent, Addr data_limit)
Definition base.cc:384
std::shared_ptr< BaseGen > createTrace(Tick duration, const std::string &trace_file, Addr addr_offset)
Definition base.cc:547
std::shared_ptr< BaseGen > createStrided(Tick duration, Addr start_addr, Addr end_addr, Addr offset, Addr block_size, Addr superblock_size, Addr stride_size, Tick min_period, Tick max_period, uint8_t read_percent, Addr data_limit)
Definition base.cc:530
std::shared_ptr< BaseGen > createDramRot(Tick duration, Addr start_addr, Addr end_addr, Addr blocksize, Tick min_period, Tick max_period, uint8_t read_percent, Addr data_limit, unsigned int num_seq_pkts, unsigned int page_size, unsigned int nbr_of_banks, unsigned int nbr_of_banks_util, enums::AddrMap addr_mapping, unsigned int nbr_of_ranks, unsigned int max_seq_count_per_rank)
Definition base.cc:436
void transition()
Transition to the next generator.
Definition base.cc:230
System *const system
The system used to determine which mode we are currently operating in.
Definition base.hh:76
std::shared_ptr< BaseGen > activeGenerator
Currently active generator.
Definition base.hh:343
std::shared_ptr< BaseGen > createExit(Tick duration)
Definition base.cc:377
std::shared_ptr< BaseGen > createNvm(Tick duration, Addr start_addr, Addr end_addr, Addr blocksize, Tick min_period, Tick max_period, uint8_t read_percent, Addr data_limit, unsigned int num_seq_pkts, unsigned int buffer_size, unsigned int nbr_of_banks, unsigned int nbr_of_banks_util, enums::AddrMap addr_mapping, unsigned int nbr_of_ranks)
Definition base.cc:506
std::shared_ptr< BaseGen > createDram(Tick duration, Addr start_addr, Addr end_addr, Addr blocksize, Tick min_period, Tick max_period, uint8_t read_percent, Addr data_limit, unsigned int num_seq_pkts, unsigned int page_size, unsigned int nbr_of_banks, unsigned int nbr_of_banks_util, enums::AddrMap addr_mapping, unsigned int nbr_of_ranks)
Definition base.cc:412
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition base.cc:132
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition base.cc:152
std::shared_ptr< BaseGen > createRandom(Tick duration, Addr start_addr, Addr end_addr, Addr blocksize, Tick min_period, Tick max_period, uint8_t read_percent, Addr data_limit)
Definition base.cc:398
virtual std::string name() const
Definition named.hh:47
bool isTimingMode() const
Is the system in timing mode?
Definition system.hh:270
The traffic generator is a module that generates stimuli for the memory system, based on a collection...
void serialize(CheckpointOut &cp) const override
Serialize an object.
void parseConfig()
Parse the config file and build the state map and transition matrix.
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
std::shared_ptr< BaseGen > nextGenerator() override
uint32_t currState
Index of the current state.
TrafficGen(const TrafficGenParams &p)
std::unordered_map< uint32_t, std::shared_ptr< BaseGen > > states
Map of generator states.
const std::string configFile
The config file to parse.
size_t nextState()
Use the transition matrix to find the next state index.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
std::string resolveFile(const std::string &name)
Resolve a file path in the configuration file.
std::vector< std::vector< double > > transitionMatrix
State transition matrix.
STL vector class.
Definition stl.hh:37
Random random_mt
Definition random.cc:99
static constexpr T divCeil(const T &a, const U &b)
Definition intmath.hh:110
std::enable_if_t< std::is_integral_v< T >, T > random()
Use the SFINAE idiom to choose an implementation based on whether the type is integral or floating po...
Definition random.hh:90
#define fatal(...)
This implements a cprintf based fatal() function.
Definition logging.hh:200
virtual void initState()
initState() is called on each SimObject when not restoring from a checkpoint.
Definition sim_object.cc:91
#define warn(...)
Definition logging.hh:256
Bitfield< 4, 0 > mode
Definition misc_types.hh:74
Bitfield< 5 > t
Definition misc_types.hh:71
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 23, 0 > offset
Definition types.hh:144
Bitfield< 33 > id
Bitfield< 24, 22 > is
Bitfield< 0 > p
Bitfield< 18 > sum
Definition misc.hh:1198
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
std::ostream CheckpointOut
Definition serialize.hh:66
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
uint64_t Tick
Tick count type.
Definition types.hh:58
std::string csprintf(const char *format, const Args &...args)
Definition cprintf.hh:161
#define UNSERIALIZE_SCALAR(scalar)
Definition serialize.hh:575
#define SERIALIZE_SCALAR(scalar)
Definition serialize.hh:568
Struct to represent a probabilistic transition during parsing.
const std::string & name()
Definition trace.cc:48

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