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)
138 init = timer.
End() / 1000.0;
139 DEB(
"initialization took " << init <<
"s");
144 simu = timer.
End() / 1000.0;
145 DEB(
"run took " << simu <<
"s");
227 template <
typename T>
228 void Log(T label)
const;
253 << std::setw(
g_fwidth) << run.period);
268 m_scheduler +=
": insertion order: " + std::string(calRev ?
"reverse" :
"normal");
275 Bench bench(pop, total);
285 auto prime = bench.
Run();
289 for (uint64_t i = 0; i < runs; i++)
291 auto run = bench.
Run();
307 <<
"Initialization:" << std::left <<
"Simulation:");
308 LOG(std::left << std::setw(
g_fwidth) <<
"" << std::left << std::setw(
g_fwidth) <<
"Time (s)"
309 << std::left << std::setw(
g_fwidth) <<
"Rate (ev/s)" << std::left
311 <<
"Time (s)" << std::left << std::setw(
g_fwidth) <<
"Rate (ev/s)" << std::left
313 LOG(std::setfill(
'-') << std::right << std::setw(
g_fwidth) <<
" " << std::right
315 << std::right << std::setw(
g_fwidth) <<
" " << std::right
317 << std::right << std::setw(
g_fwidth) <<
" " << std::setfill(
' '));
345 uint64_t count = n + 1;
347#define ACCUMULATE(phase, field) \
348 deltaPre = run.phase.field - average.phase.field; \
349 average.phase.field += deltaPre / count; \
350 deltaPost = run.phase.field - average.phase.field; \
351 moment2.phase.field += deltaPre * deltaPost
364 {std::sqrt(moment2.init.time / n),
365 std::sqrt(moment2.init.rate / n),
366 std::sqrt(moment2.init.period / n)},
367 {std::sqrt(moment2.run.time / n),
368 std::sqrt(moment2.run.rate / n),
369 std::sqrt(moment2.run.period / n)},
372 average.
Log(
"average");
395 if (filename.empty())
397 LOG(
" Event time distribution: default exponential");
408 LOG(
" Event time distribution: from stdin");
413 LOG(
" Event time distribution: from " << filename);
414 input =
new std::ifstream(filename);
418 std::vector<double> nsValues;
420 while (!input->eof())
424 auto ns = (uint64_t)(value * 1000000000);
425 nsValues.push_back(ns);
434 LOG(
" Found " << nsValues.size() <<
" entries");
436 drv->SetValueArray(&nsValues[0], nsValues.size());
444main(
int argc,
char* argv[])
446 bool allSched =
false;
447 bool schedCal =
false;
448 bool schedHeap =
false;
449 bool schedList =
false;
450 bool schedMap =
false;
451 bool schedPQ =
false;
453 uint64_t pop = 100000;
454 uint64_t total = 1000000;
456 std::string filename =
"";
460 cmd.Usage(
"Benchmark the simulator scheduler.\n"
462 "Event intervals are taken from one of:\n"
463 " an exponential distribution, with mean 100 ns,\n"
464 " an ascii file, given by the --file=\"<filename>\" argument,\n"
465 " or standard input, by the argument --file=\"-\"\n"
466 "In the case of either --file form, the input is expected\n"
467 "to be ascii, giving the relative event times in ns.\n"
469 "If no scheduler is specified the MapScheduler will be run.");
470 cmd.AddValue(
"all",
"use all schedulers", allSched);
471 cmd.AddValue(
"cal",
"use CalendarScheduler", schedCal);
472 cmd.AddValue(
"calrev",
"reverse ordering in the CalendarScheduler", calRev);
473 cmd.AddValue(
"heap",
"use HeapScheduler", schedHeap);
474 cmd.AddValue(
"list",
"use ListScheduler", schedList);
475 cmd.AddValue(
"map",
"use MapScheduler (default)", schedMap);
476 cmd.AddValue(
"pri",
"use PriorityQueue", schedPQ);
477 cmd.AddValue(
"debug",
"enable debugging output",
g_debug);
478 cmd.AddValue(
"pop",
"event population size", pop);
479 cmd.AddValue(
"total",
"total number of events to run", total);
480 cmd.AddValue(
"runs",
"number of runs", runs);
481 cmd.AddValue(
"file",
"file of relative event times", filename);
482 cmd.AddValue(
"prec",
"printed output precision",
g_fwidth);
483 cmd.Parse(argc, argv);
489 LOGME(
" Benchmark the simulator scheduler");
490 LOG(
" Event population size: " << pop);
491 LOG(
" Total events per run: " << total);
492 LOG(
" Number of runs per scheduler: " << runs);
493 DEB(
"debugging is ON");
497 schedCal = schedHeap = schedList = schedMap = schedPQ =
true;
500 if (!(schedCal || schedHeap || schedList || schedMap || schedPQ))
510 factory.SetTypeId(
"ns3::CalendarScheduler");
512 BenchSuite(factory, pop, total, runs, eventStream, calRev).Log();
516 BenchSuite(factory, pop, total, runs, eventStream, !calRev).Log();
521 factory.SetTypeId(
"ns3::HeapScheduler");
522 BenchSuite(factory, pop, total, runs, eventStream, calRev).Log();
526 factory.SetTypeId(
"ns3::ListScheduler");
527 auto listTotal = total;
530 LOG(
"Running List scheduler with 1/10 total events");
533 BenchSuite(factory, pop, listTotal, runs, eventStream, calRev).Log();
537 factory.SetTypeId(
"ns3::MapScheduler");
538 BenchSuite(factory, pop, total, runs, eventStream, calRev).Log();
542 factory.SetTypeId(
"ns3::PriorityQueueScheduler");
543 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.