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.