9#include "ns3/core-module.h"
26#define LOG(x) std::cout << x << std::endl
28#define LOGME(x) LOG(g_me << x)
55 Bench(
const uint64_t population,
const uint64_t total)
137 init = timer.
End() / 1000.0;
138 DEB(
"initialization took " << init <<
"s");
143 simu = timer.
End() / 1000.0;
144 DEB(
"run took " << simu <<
"s");
226 template <
typename T>
227 void Log(T label)
const;
252 << std::setw(
g_fwidth) << run.period);
267 m_scheduler +=
": insertion order: " + std::string(calRev ?
"reverse" :
"normal");
274 Bench bench(pop, total);
284 auto prime = bench.
Run();
288 for (uint64_t i = 0; i < runs; i++)
290 auto run = bench.
Run();
305 <<
"Initialization:" << std::left <<
"Simulation:");
306 LOG(std::left << std::setw(
g_fwidth) <<
"" << std::left << std::setw(
g_fwidth) <<
"Time (s)"
307 << std::left << std::setw(
g_fwidth) <<
"Rate (ev/s)" << std::left
309 <<
"Time (s)" << std::left << std::setw(
g_fwidth) <<
"Rate (ev/s)" << std::left
311 LOG(std::setfill(
'-') << std::right << std::setw(
g_fwidth) <<
" " << std::right
313 << std::right << std::setw(
g_fwidth) <<
" " << std::right
315 << std::right << std::setw(
g_fwidth) <<
" " << std::setfill(
' '));
343 uint64_t count = n + 1;
345#define ACCUMULATE(phase, field) \
346 deltaPre = run.phase.field - average.phase.field; \
347 average.phase.field += deltaPre / count; \
348 deltaPost = run.phase.field - average.phase.field; \
349 moment2.phase.field += deltaPre * deltaPost
362 {std::sqrt(moment2.init.time / n),
363 std::sqrt(moment2.init.rate / n),
364 std::sqrt(moment2.init.period / n)},
365 {std::sqrt(moment2.run.time / n),
366 std::sqrt(moment2.run.rate / n),
367 std::sqrt(moment2.run.period / n)},
370 average.
Log(
"average");
392 if (filename.empty())
394 LOG(
" Event time distribution: default exponential");
405 LOG(
" Event time distribution: from stdin");
410 LOG(
" Event time distribution: from " << filename);
411 input =
new std::ifstream(filename);
415 std::vector<double> nsValues;
417 while (!input->eof())
421 auto ns = (uint64_t)(value * 1000000000);
422 nsValues.push_back(ns);
431 LOG(
" Found " << nsValues.size() <<
" entries");
433 drv->SetValueArray(&nsValues[0], nsValues.size());
441main(
int argc,
char* argv[])
443 bool allSched =
false;
444 bool schedCal =
false;
445 bool schedHeap =
false;
446 bool schedList =
false;
447 bool schedMap =
false;
448 bool schedPQ =
false;
450 uint64_t pop = 100000;
451 uint64_t total = 1000000;
453 std::string filename =
"";
457 cmd.Usage(
"Benchmark the simulator scheduler.\n"
459 "Event intervals are taken from one of:\n"
460 " an exponential distribution, with mean 100 ns,\n"
461 " an ascii file, given by the --file=\"<filename>\" argument,\n"
462 " or standard input, by the argument --file=\"-\"\n"
463 "In the case of either --file form, the input is expected\n"
464 "to be ascii, giving the relative event times in ns.\n"
466 "If no scheduler is specified the MapScheduler will be run.");
467 cmd.AddValue(
"all",
"use all schedulers", allSched);
468 cmd.AddValue(
"cal",
"use CalendarScheduler", schedCal);
469 cmd.AddValue(
"calrev",
"reverse ordering in the CalendarScheduler", calRev);
470 cmd.AddValue(
"heap",
"use HeapScheduler", schedHeap);
471 cmd.AddValue(
"list",
"use ListScheduler", schedList);
472 cmd.AddValue(
"map",
"use MapScheduler (default)", schedMap);
473 cmd.AddValue(
"pri",
"use PriorityQueue", schedPQ);
474 cmd.AddValue(
"debug",
"enable debugging output",
g_debug);
475 cmd.AddValue(
"pop",
"event population size", pop);
476 cmd.AddValue(
"total",
"total number of events to run", total);
477 cmd.AddValue(
"runs",
"number of runs", runs);
478 cmd.AddValue(
"file",
"file of relative event times", filename);
479 cmd.AddValue(
"prec",
"printed output precision",
g_fwidth);
480 cmd.Parse(argc, argv);
486 LOGME(
" Benchmark the simulator scheduler");
487 LOG(
" Event population size: " << pop);
488 LOG(
" Total events per run: " << total);
489 LOG(
" Number of runs per scheduler: " << runs);
490 DEB(
"debugging is ON");
494 schedCal = schedHeap = schedList = schedMap = schedPQ =
true;
497 if (!(schedCal || schedHeap || schedList || schedMap || schedPQ))
507 factory.SetTypeId(
"ns3::CalendarScheduler");
509 BenchSuite(factory, pop, total, runs, eventStream, calRev).Log();
513 BenchSuite(factory, pop, total, runs, eventStream, !calRev).Log();
518 factory.SetTypeId(
"ns3::HeapScheduler");
519 BenchSuite(factory, pop, total, runs, eventStream, calRev).Log();
523 factory.SetTypeId(
"ns3::ListScheduler");
524 auto listTotal = total;
527 LOG(
"Running List scheduler with 1/10 total events");
530 BenchSuite(factory, pop, listTotal, runs, eventStream, calRev).Log();
534 factory.SetTypeId(
"ns3::MapScheduler");
535 BenchSuite(factory, pop, total, runs, eventStream, calRev).Log();
539 factory.SetTypeId(
"ns3::PriorityQueueScheduler");
540 BenchSuite(factory, pop, total, runs, eventStream, calRev).Log();
Ptr< RandomVariableStream > GetRandomStream(std::string filename)
Create a RandomVariableStream to generate next event delays.
bool g_debug
Flag to write debugging output.
#define LOGME(x)
Log with program name prefix.
int g_fwidth
Output field width for numeric data.
std::string g_me
Name of this program.
#define ACCUMULATE(phase, field)
#define LOG(x)
Log to std::cout.
#define DEB(x)
Log debugging output.
Benchmark instance which can do a single run.
void SetRandomStream(Ptr< RandomVariableStream > stream)
Set the event delay interval random stream.
uint64_t m_population
Event population size.
void SetTotal(const uint64_t total)
Set the total number of events to execute.
Result Run()
Run the benchmark as configured.
Ptr< RandomVariableStream > m_rand
Stream for event delays.
uint64_t m_count
Count of events executed so far.
Bench(const uint64_t population, const uint64_t total)
Constructor.
void SetPopulation(const uint64_t population)
Set the number of events to populate the scheduler with.
uint64_t m_total
Total number of events to execute.
Benchmark which performs an ensemble of runs.
void Log() const
Write the results to LOG()
BenchSuite(ObjectFactory &factory, uint64_t pop, uint64_t total, uint64_t runs, Ptr< RandomVariableStream > eventStream, bool calRev)
Perform the runs for a single scheduler type.
void Header() const
Print the table header.
std::vector< Result > m_results
Store for the run results.
std::string m_scheduler
Descriptive string for the scheduler.
AttributeValue implementation for Boolean.
Parse command-line arguments.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Instantiate subclasses of ns3::Object.
TypeId GetTypeId() const
Get the TypeId which will be created by this ObjectFactory.
Smart pointer class similar to boost::intrusive_ptr.
virtual double GetValue()=0
Get the next random value drawn from the distribution.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
static Time Now()
Return the current simulation virtual time.
static void Run()
Run the simulation.
static void SetScheduler(ObjectFactory schedulerFactory)
Set the scheduler type with an ObjectFactory.
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Measure elapsed wall clock time in milliseconds.
int64_t End()
Stop measuring the time since Start() was called.
void Start()
Start a measure.
Simulation virtual time values and global simulation resolution.
std::string GetName() const
Get the name.
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::StringValue attribute value declarations.
uint64_t events
Number of events executed.
uint64_t pop
Event population.
double init
Time (s) for initialization.
double simu
Time (s) for simulation.
Statistics from a single phase, init or run.
double rate
Phase event rate (events/s).
double period
Phase period (s/event).
double time
Phase run time time (s).
Results from initialization and execution of a single run.
PhaseResult init
Initialization phase results.
static Result Bench(Bench::Result r)
Construct from the individual run result.
void Log(T label) const
Log this result.
PhaseResult run
Run (simulation) phase results.