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

Generated on Fri Jul 3 2020 15:53:01 for gem5 by doxygen 1.8.13