A Discrete-Event Network Simulator
API
bench-simulator.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2006 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 
21 #include <iomanip>
22 #include <iostream>
23 #include <fstream>
24 #include <vector>
25 #include <string.h>
26 
27 #include "ns3/core-module.h"
28 
29 using namespace ns3;
30 
31 
32 bool g_debug = false;
33 
34 std::string g_me;
35 #define LOG(x) std::cout << x << std::endl
36  #define LOGME(x) LOG (g_me << x)
37  #define DEB(x) if (g_debug) { LOGME (x); }
38 
39 // Output field width
40 int g_fwidth = 6;
41 
43 class Bench
44 {
45 public:
51  Bench (const uint32_t population, const uint32_t total)
52  : m_population (population),
53  m_total (total),
54  m_count (0)
55  {
56  }
57 
63  {
64  m_rand = stream;
65  }
66 
71  void SetPopulation (const uint32_t population)
72  {
73  m_population = population;
74  }
75 
80  void SetTotal (const uint32_t total)
81  {
82  m_total = total;
83  }
84 
86  void RunBench (void);
87 private:
89  void Cb (void);
90 
92  uint32_t m_population;
93  uint32_t m_total;
94  uint32_t m_count;
95 };
96 
97 void
99 {
100  SystemWallClockMs time;
101  double init, simu;
102 
103  DEB ("initializing");
104  m_count = 0;
105 
106 
107  time.Start ();
108  for (uint32_t i = 0; i < m_population; ++i)
109  {
110  Time at = NanoSeconds (m_rand->GetValue ());
111  Simulator::Schedule (at, &Bench::Cb, this);
112  }
113  init = time.End ();
114  init /= 1000;
115  DEB ("initialization took " << init << "s");
116 
117  DEB ("running");
118  time.Start ();
119  Simulator::Run ();
120  simu = time.End ();
121  simu /= 1000;
122  DEB ("run took " << simu << "s");
123 
124  LOG (std::setw (g_fwidth) << init <<
125  std::setw (g_fwidth) << (m_population / init) <<
126  std::setw (g_fwidth) << (init / m_population) <<
127  std::setw (g_fwidth) << simu <<
128  std::setw (g_fwidth) << (m_count / simu) <<
129  std::setw (g_fwidth) << (simu / m_count));
130 
131 }
132 
133 void
134 Bench::Cb (void)
135 {
136  if (m_count >= m_total)
137  {
138  return;
139  }
140  DEB ("event at " << Simulator::Now ().GetSeconds () << "s");
141 
142  Time after = NanoSeconds (m_rand->GetValue ());
143  Simulator::Schedule (after, &Bench::Cb, this);
144  ++m_count;
145 }
146 
147 
149 GetRandomStream (std::string filename)
150 {
151  Ptr<RandomVariableStream> stream = 0;
152 
153  if (filename == "")
154  {
155  LOGME ("using default exponential distribution");
156  Ptr<ExponentialRandomVariable> erv = CreateObject<ExponentialRandomVariable> ();
157  erv->SetAttribute ("Mean", DoubleValue (100));
158  stream = erv;
159  }
160  else
161  {
162  std::istream *input;
163 
164  if (filename == "-")
165  {
166  LOGME ("using event distribution from stdin");
167  input = &std::cin;
168  }
169  else
170  {
171  LOGME ("using event distribution from " << filename);
172  input = new std::ifstream (filename.c_str ());
173  }
174 
175  double value;
176  std::vector<double> nsValues;
177 
178  while (!input->eof ())
179  {
180  if (*input >> value)
181  {
182  uint64_t ns = (uint64_t) (value * 1000000000);
183  nsValues.push_back (ns);
184  }
185  else
186  {
187  input->clear ();
188  std::string line;
189  *input >> line;
190  }
191  }
192  LOGME ("found " << nsValues.size () << " entries");
193  Ptr<DeterministicRandomVariable> drv = CreateObject<DeterministicRandomVariable> ();
194  drv->SetValueArray (&nsValues[0], nsValues.size ());
195  stream = drv;
196  }
197 
198  return stream;
199 }
200 
201 
202 
203 int main (int argc, char *argv[])
204 {
205 
206  bool schedCal = false;
207  bool schedHeap = false;
208  bool schedList = false;
209  bool schedMap = true;
210 
211  uint32_t pop = 100000;
212  uint32_t total = 1000000;
213  uint32_t runs = 1;
214  std::string filename = "";
215 
217  cmd.Usage ("Benchmark the simulator scheduler.\n"
218  "\n"
219  "Event intervals are taken from one of:\n"
220  " an exponential distribution, with mean 100 ns,\n"
221  " an ascii file, given by the --file=\"<filename>\" argument,\n"
222  " or standard input, by the argument --file=\"-\"\n"
223  "In the case of either --file form, the input is expected\n"
224  "to be ascii, giving the relative event times in ns.");
225  cmd.AddValue ("cal", "use CalendarSheduler", schedCal);
226  cmd.AddValue ("heap", "use HeapScheduler", schedHeap);
227  cmd.AddValue ("list", "use ListSheduler", schedList);
228  cmd.AddValue ("map", "use MapScheduler (default)", schedMap);
229  cmd.AddValue ("debug", "enable debugging output", g_debug);
230  cmd.AddValue ("pop", "event population size (default 1E5)", pop);
231  cmd.AddValue ("total", "total number of events to run (default 1E6)", total);
232  cmd.AddValue ("runs", "number of runs (default 1)", runs);
233  cmd.AddValue ("file", "file of relative event times", filename);
234  cmd.AddValue ("prec", "printed output precision", g_fwidth);
235  cmd.Parse (argc, argv);
236  g_me = cmd.GetName () + ": ";
237  g_fwidth += 6; // 5 extra chars in '2.000002e+07 ': . e+0 _
238 
239  ObjectFactory factory ("ns3::MapScheduler");
240  if (schedCal)
241  {
242  factory.SetTypeId ("ns3::CalendarScheduler");
243  }
244  if (schedHeap)
245  {
246  factory.SetTypeId ("ns3::HeapScheduler");
247  }
248  if (schedList)
249  {
250  factory.SetTypeId ("ns3::ListScheduler");
251  }
252  Simulator::SetScheduler (factory);
253 
254  LOGME (std::setprecision (g_fwidth - 6));
255  DEB ("debugging is ON");
256 
257  LOGME ("scheduler: " << factory.GetTypeId ().GetName ());
258  LOGME ("population: " << pop);
259  LOGME ("total events: " << total);
260  LOGME ("runs: " << runs);
261 
262  Bench *bench = new Bench (pop, total);
263  bench->SetRandomStream (GetRandomStream (filename));
264 
265  // table header
266  LOG ("");
267  LOG (std::left << std::setw (g_fwidth) << "Run #" <<
268  std::left << std::setw (3 * g_fwidth) << "Inititialization:" <<
269  std::left << std::setw (3 * g_fwidth) << "Simulation:");
270  LOG (std::left << std::setw (g_fwidth) << "" <<
271  std::left << std::setw (g_fwidth) << "Time (s)" <<
272  std::left << std::setw (g_fwidth) << "Rate (ev/s)" <<
273  std::left << std::setw (g_fwidth) << "Per (s/ev)" <<
274  std::left << std::setw (g_fwidth) << "Time (s)" <<
275  std::left << std::setw (g_fwidth) << "Rate (ev/s)" <<
276  std::left << std::setw (g_fwidth) << "Per (s/ev)" );
277  LOG (std::setfill ('-') <<
278  std::right << std::setw (g_fwidth) << " " <<
279  std::right << std::setw (g_fwidth) << " " <<
280  std::right << std::setw (g_fwidth) << " " <<
281  std::right << std::setw (g_fwidth) << " " <<
282  std::right << std::setw (g_fwidth) << " " <<
283  std::right << std::setw (g_fwidth) << " " <<
284  std::right << std::setw (g_fwidth) << " " <<
285  std::setfill (' ')
286  );
287 
288  // prime
289  DEB ("priming");
290  std::cout << std::left << std::setw (g_fwidth) << "(prime)";
291  bench->RunBench ();
292 
293  bench->SetPopulation (pop);
294  bench->SetTotal (total);
295  for (uint32_t i = 0; i < runs; i++)
296  {
297  std::cout << std::setw (g_fwidth) << i;
298 
299  bench->RunBench ();
300  }
301 
302  LOG ("");
304  delete bench;
305  return 0;
306 }
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
Ptr< RandomVariableStream > m_rand
random variable
void RunBench(void)
Run function.
ns3::StringValue attribute value declarations.
static void Run(void)
Run the simulation.
Definition: simulator.cc:170
cmd
Definition: second.py:35
Bench class.
Ptr< RandomVariableStream > GetRandomStream(std::string filename)
Measure elapsed wall clock time in milliseconds.
#define LOGME(x)
Bench(const uint32_t population, const uint32_t total)
constructor
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1390
void SetPopulation(const uint32_t population)
Set population function.
uint32_t m_total
total
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1094
void Start(void)
Start a measure.
uint32_t m_population
population
Parse command-line arguments.
Definition: command-line.h:212
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:134
#define LOG(x)
int g_fwidth
std::string g_me
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint32_t m_count
count
void SetRandomStream(Ptr< RandomVariableStream > stream)
Set random stream.
bool g_debug
static void SetScheduler(ObjectFactory schedulerFactory)
Set the scheduler type with an ObjectFactory.
Definition: simulator.cc:156
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:193
Instantiate subclasses of ns3::Object.
This class can be used to hold variables of floating point type such as &#39;double&#39; or &#39;float&#39;...
Definition: double.h:41
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:187
int64_t End(void)
Stop measuring the time since Start() was called.
void SetTotal(const uint32_t total)
Set total function.
void Cb(void)
callback function
#define DEB(x)