src/stats/doc/statistics.rst
changeset 7306 611184f5148a
parent 7204 052d30ceb700
child 10408 5c604e8ec2e1
equal deleted inserted replaced
7305:4f64f4298183 7306:611184f5148a
     1 .. include:: replace.txt
     1 .. include:: replace.txt
     2 
     2 
     3 Statistics
     3 Statistical Framework
     4 ----------
     4 ---------------------
     5 
     5 
     6 *Placeholder chapter*
     6 This chapter outlines work on simulation data collection and the
     7 
     7 statistical framework for ns-3.
     8 This wiki page: `This wiki page
     8 
     9 <http://www.nsnam.org/wiki/index.php/Statistical_Framework_for_Network_Simulation>`_
     9 The source code for the statistical framework lives in the directory
    10 contains information about the proposed statistical framework that is located in
    10 ``src/stats``.
    11 ``src/stats`` directory.
    11 
       
    12 Goals
       
    13 *****
       
    14 
       
    15 Primary objectives for this effort are the following:
       
    16 
       
    17 * Provide functionality to record, calculate, and present data and statistics for analysis of network simulations.
       
    18 * Boost simulation performance by reducing the need to generate extensive trace logs in order to collect data.
       
    19 * Enable simulation control via online statistics, e.g. terminating simulations or repeating trials.
       
    20 
       
    21 Derived sub-goals and other target features include the following:
       
    22 
       
    23 * Integration with the existing ns-3 tracing system as the basic instrumentation framework of the internal simulation engine, e.g. network stacks, net devices, and channels.
       
    24 * Enabling users to utilize the statistics framework without requiring use of the tracing system.
       
    25 * Helping users create, aggregate, and analyze data over multiple trials.
       
    26 * Support for user created instrumentation, e.g. of application specific events and measures.
       
    27 * Low memory and CPU overhead when the package is not in use.
       
    28 * Leveraging existing analysis and output tools as much as possible.  The framework may provide some basic statistics, but the focus is on collecting data and making it accessible for manipulation in established tools.
       
    29 * Eventual support for distributing independent replications is important but not included in the first round of features.
       
    30 
       
    31 Overview
       
    32 ********
       
    33 
       
    34 The statistics framework includes the following features:
       
    35 
       
    36 * The core framework and two basic data collectors: A counter, and a min/max/avg/total observer.
       
    37 * Extensions of those to easily work with times and packets.
       
    38 * Plaintext output formatted for omnetpp.
       
    39 * Database output using sqlite3, a standalone, lightweight, high performance SQL engine.
       
    40 * Mandatory and open ended metadata for describing and working with runs.
       
    41 * An example based on the notional experiment of examining the properties of NS-3's default ad hoc WiFi performance.  It incorporates the following:
       
    42 
       
    43   * Constructs of a two node ad hoc WiFi network, with the nodes a parameterized distance apart.
       
    44   * UDP traffic source and sink applications with slightly different behavior and measurement hooks than the stock classes.
       
    45   * Data collection from the NS-3 core via existing trace signals, in particular data on frames transmitted and received by the WiFi MAC objects.
       
    46   * Instrumentation of custom applications by connecting new trace signals to the stat framework, as well as via direct updates.  Information is recorded about total packets sent and received, bytes transmitted, and end-to-end delay.
       
    47   * An example of using packet tags to track end-to-end delay.
       
    48   * A simple control script which runs a number of trials of the experiment at varying distances and queries the resulting database to produce a graph using GNUPlot.
       
    49 
       
    50 To-Do
       
    51 *****
       
    52 
       
    53 High priority items include:
       
    54 
       
    55 * Inclusion of online statistics code, e.g. for memory efficient confidence intervals.
       
    56 * Provisions in the data collectors for terminating runs, i.e. when a threshold or confidence is met.
       
    57 * Data collectors for logging samples over time, and output to the various formats.
       
    58 * Demonstrate writing simple cyclic event glue to regularly poll some value.
       
    59 
       
    60 Each of those should prove straightforward to incorporate in the current framework.
       
    61 
       
    62 Approach
       
    63 ********
       
    64 
       
    65 The framework is based around the following core principles:
       
    66 
       
    67 * One experiment trial is conducted by one instance of a simulation program, whether in parallel or serially.
       
    68 * A control script executes instances of the simulation, varying parameters as necessary.
       
    69 * Data is collected and stored for plotting and analysis using external scripts and existing tools.
       
    70 * Measures within the ns-3 core are taken by connecting the stat framework to existing trace signals.
       
    71 * Trace signals or direct manipulation of the framework may be used to instrument custom simulation code.
       
    72 
       
    73 Those basic components of the framework and their interactions are depicted in the following figure.
       
    74 
       
    75 .. image:: figures/Stat-framework-arch.png
       
    76 
       
    77 
       
    78 Example
       
    79 *******
       
    80 
       
    81 This section goes through the process of constructing an experiment in the framework and producing data for analysis (graphs) from it, demonstrating the structure and API along the way.
       
    82 
       
    83 Question
       
    84 ++++++++
       
    85 
       
    86 ''What is the (simulated) performance of ns-3's WiFi NetDevices (using the default settings)?  How far apart can wireless nodes be in a simulation before they cannot communicate reliably?''
       
    87 
       
    88 * Hypothesis: Based on knowledge of real life performance, the nodes should communicate reasonably well to at least 100m apart.  Communication beyond 200m shouldn't be feasible.
       
    89 
       
    90 Although not a very common question in simulation contexts, this is an important property of which simulation developers should have a basic understanding.  It is also a common study done on live hardware.
       
    91 
       
    92 Simulation Program
       
    93 ++++++++++++++++++
       
    94 
       
    95 The first thing to do in implementing this experiment is developing the simulation program.  The code for this example can be found in ``examples/stats/wifi-example-sim.cc``.  It does the following main steps.
       
    96 
       
    97 * Declaring parameters and parsing the command line using ``ns3::CommandLine``.
       
    98 
       
    99   ::
       
   100 
       
   101     CommandLine cmd;
       
   102     cmd.AddValue("distance", "Distance apart to place nodes (in meters).",
       
   103                  distance);
       
   104     cmd.AddValue("format", "Format to use for data output.",
       
   105                  format);
       
   106     cmd.AddValue("experiment", "Identifier for experiment.",
       
   107                  experiment);
       
   108     cmd.AddValue("strategy", "Identifier for strategy.",
       
   109                  strategy);
       
   110     cmd.AddValue("run", "Identifier for run.",
       
   111                  runID);
       
   112     cmd.Parse (argc, argv);
       
   113 
       
   114 * Creating nodes and network stacks using ``ns3::NodeContainer``, ``ns3::WiFiHelper``, and ``ns3::InternetStackHelper``.
       
   115 
       
   116   ::
       
   117 
       
   118     NodeContainer nodes;
       
   119     nodes.Create(2);
       
   120 
       
   121     WifiHelper wifi;
       
   122     wifi.SetMac("ns3::AdhocWifiMac");
       
   123     wifi.SetPhy("ns3::WifiPhy");
       
   124     NetDeviceContainer nodeDevices = wifi.Install(nodes);
       
   125 
       
   126     InternetStackHelper internet;
       
   127     internet.Install(nodes);
       
   128     Ipv4AddressHelper ipAddrs;
       
   129     ipAddrs.SetBase("192.168.0.0", "255.255.255.0");
       
   130     ipAddrs.Assign(nodeDevices);
       
   131 
       
   132 * Positioning the nodes using ``ns3::MobilityHelper``.  By default the nodes have static mobility and won't move, but must be positioned the given distance apart.  There are several ways to do this; it is done here using ``ns3::ListPositionAllocator``, which draws positions from a given list.
       
   133 
       
   134   ::
       
   135 
       
   136     MobilityHelper mobility;
       
   137     Ptr<ListPositionAllocator> positionAlloc =
       
   138       CreateObject<ListPositionAllocator>();
       
   139     positionAlloc->Add(Vector(0.0, 0.0, 0.0));
       
   140     positionAlloc->Add(Vector(0.0, distance, 0.0));
       
   141     mobility.SetPositionAllocator(positionAlloc);
       
   142     mobility.Install(nodes);
       
   143 
       
   144 * Installing a traffic generator and a traffic sink.  The stock ``Applications`` could be used, but the example includes custom objects in ``src/test/test02-apps.(cc|h)``.  These have a simple behavior, generating a given number of packets spaced at a given interval.  As there is only one of each they are installed manually; for a larger set the ``ns3::ApplicationHelper`` class could be used.  The commented-out ``Config::Set`` line changes the destination of the packets, set to broadcast by default in this example.  Note that in general WiFi may have different performance for broadcast and unicast frames due to different rate control and MAC retransmission policies.
       
   145 
       
   146   ::
       
   147 
       
   148     Ptr<Node> appSource = NodeList::GetNode(0);  
       
   149     Ptr<Sender> sender = CreateObject<Sender>();
       
   150     appSource->AddApplication(sender);
       
   151     sender->Start(Seconds(1));
       
   152 
       
   153     Ptr<Node> appSink = NodeList::GetNode(1);  
       
   154     Ptr<Receiver> receiver = CreateObject<Receiver>();
       
   155     appSink->AddApplication(receiver);
       
   156     receiver->Start(Seconds(0));
       
   157 
       
   158     //  Config::Set("/NodeList/*/ApplicationList/*/$Sender/Destination",
       
   159     //              Ipv4AddressValue("192.168.0.2"));
       
   160 
       
   161 * Configuring the data and statistics to be collected.  The basic paradigm is that an ``ns3::DataCollector`` object is created to hold information about this particular run, to which observers and calculators are attached to actually generate data.  Importantly, run information includes labels for the ''experiment'', ''strategy'', ''input'', and ''run''.  These are used to later identify and easily group data from multiple trials.
       
   162 
       
   163   * The experiment is the study of which this trial is a member.  Here it is on WiFi performance and distance.
       
   164   * The strategy is the code or parameters being examined in this trial.  In this example it is fixed, but an obvious extension would be to investigate different WiFi bit rates, each of which would be a different strategy.
       
   165   * The input is the particular problem given to this trial.  Here it is simply the distance between the two nodes.
       
   166   * The runID is a unique identifier for this trial with which it's information is tagged for identification in later analysis.  If no run ID is given the example program makes a (weak) run ID using the current time.
       
   167 
       
   168   Those four pieces of metadata are required, but more may be desired.  They may be added to the record using the ``ns3::DataCollector::AddMetadata()`` method.
       
   169 
       
   170   ::
       
   171 
       
   172     DataCollector data;
       
   173     data.DescribeRun(experiment,
       
   174                      strategy,
       
   175                      input,
       
   176                      runID);
       
   177     data.AddMetadata("author", "tjkopena");
       
   178 
       
   179   Actual observation and calculating is done by ``ns3::DataCalculator`` objects, of which several different types exist.  These are created by the simulation program, attached to reporting or sampling code, and then registered with the ``ns3::DataCollector`` so they will be queried later for their output.  One easy observation mechanism is to use existing trace sources, for example to instrument objects in the ns-3 core without changing their code.  Here a counter is attached directly to a trace signal in the WiFi MAC layer on the target node.
       
   180 
       
   181   ::
       
   182 
       
   183     Ptr<PacketCounterCalculator> totalRx =
       
   184       CreateObject<PacketCounterCalculator>();
       
   185     totalRx->SetKey("wifi-rx-frames");
       
   186     Config::Connect("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Rx",
       
   187                     MakeCallback(&PacketCounterCalculator::FrameUpdate,
       
   188                                       totalRx));
       
   189     data.AddDataCalculator(totalRx);
       
   190 
       
   191   Calculators may also be manipulated directly.  In this example, a counter is created and passed to the traffic sink application to be updated when packets are received.
       
   192 
       
   193   ::
       
   194 
       
   195     Ptr<CounterCalculator<> > appRx =
       
   196       CreateObject<CounterCalculator<> >();
       
   197     appRx->SetKey("receiver-rx-packets");
       
   198     receiver->SetCounter(appRx);
       
   199     data.AddDataCalculator(appRx);
       
   200 
       
   201   To increment the count, the sink's packet processing code then calls one of the calculator's update methods.
       
   202 
       
   203   ::
       
   204 
       
   205         m_calc->Update();
       
   206 
       
   207   The program includes several other examples as well, using both the primitive calculators such as ``ns3::CounterCalculator`` and those adapted for observing packets and times.  In ``src/test/test02-apps.(cc|h)`` it also creates a simple custom tag which it uses to track end-to-end delay for generated packets, reporting results to a ``ns3::TimeMinMaxAvgTotalCalculator`` data calculator.
       
   208 
       
   209 * Running the simulation, which is very straightforward once constructed.
       
   210 
       
   211   ::
       
   212 
       
   213     Simulator::Run();    
       
   214 
       
   215 * Generating either omnetpp or sqlite output, depending on the command line arguments.  To do this a ``ns3::DataOutputInterface`` object is created and configured.  The specific type of this will determine the output format.  This object is then given the ``ns3::DataCollector`` object which it interrogates to produce the output.
       
   216 
       
   217   ::
       
   218 
       
   219     Ptr<DataOutputInterface> output;
       
   220     if (format == "omnet") {
       
   221       NS_LOG_INFO("Creating omnet formatted data output.");
       
   222       output = CreateObject<OmnetDataOutput>();
       
   223     } else {
       
   224       #ifdef STAT_USE_DB
       
   225         NS_LOG_INFO("Creating sqlite formatted data output.");
       
   226         output = CreateObject<SqliteDataOutput>();
       
   227       #endif
       
   228     }
       
   229 
       
   230     output->Output(data);
       
   231 
       
   232 * Freeing any memory used by the simulation.  This should come at the end of the main function for the example.
       
   233 
       
   234   ::
       
   235 
       
   236     Simulator::Destroy();
       
   237 
       
   238 Logging
       
   239 =======
       
   240 
       
   241 To see what the example program, applications, and stat framework are doing in detail, set the ``NS_LOG`` variable appropriately.  The following will provide copious output from all three.
       
   242   
       
   243 ::
       
   244 
       
   245   export NS_LOG=StatFramework:WiFiDistanceExperiment:WiFiDistanceApps
       
   246 
       
   247 Note that this slows down the simulation extraordinarily.
       
   248 
       
   249 Sample Output
       
   250 =============
       
   251 
       
   252 Compiling and simply running the test program will append omnet++ formatted output such as the following to ``data.sca``.
       
   253 
       
   254 ::
       
   255  
       
   256   run run-1212239121
       
   257   
       
   258   attr experiment "wifi-distance-test"
       
   259   attr strategy "wifi-default"
       
   260   attr input "50"
       
   261   attr description ""
       
   262   
       
   263   attr "author" "tjkopena"
       
   264   
       
   265   scalar wifi-tx-frames count 30
       
   266   scalar wifi-rx-frames count 30
       
   267   scalar sender-tx-packets count 30
       
   268   scalar receiver-rx-packets count 30
       
   269   scalar tx-pkt-size count 30
       
   270   scalar tx-pkt-size total 1920
       
   271   scalar tx-pkt-size average 64
       
   272   scalar tx-pkt-size max 64
       
   273   scalar tx-pkt-size min 64
       
   274   scalar delay count 30
       
   275   scalar delay total 5884980ns
       
   276   scalar delay average 196166ns
       
   277   scalar delay max 196166ns
       
   278   scalar delay min 196166ns
       
   279 
       
   280 Control Script
       
   281 ++++++++++++++
       
   282 
       
   283 In order to automate data collection at a variety of inputs (distances), a simple Bash script is used to execute a series of simulations.  It can be found at ``examples/stats/wifi-example-db.sh``.  The script runs through a set of distances, collecting the results into an sqlite3 database.  At each distance five trials are conducted to give a better picture of expected performance.  The entire experiment takes only a few dozen seconds to run on a low end machine as there is no output during the simulation and little traffic is generated.
       
   284   
       
   285 ::
       
   286 
       
   287   #!/bin/sh
       
   288   
       
   289   DISTANCES="25 50 75 100 125 145 147 150 152 155 157 160 162 165 167 170 172 175 177 180"
       
   290   TRIALS="1 2 3 4 5"
       
   291   
       
   292   echo WiFi Experiment Example
       
   293   
       
   294   if [ -e data.db ]
       
   295   then
       
   296     echo Kill data.db?
       
   297     read ANS
       
   298     if [ "$ANS" = "yes" -o "$ANS" = "y" ]
       
   299     then
       
   300       echo Deleting database
       
   301       rm data.db
       
   302     fi
       
   303   fi
       
   304   
       
   305   for trial in $TRIALS
       
   306   do
       
   307     for distance in $DISTANCES
       
   308     do
       
   309       echo Trial $trial, distance $distance
       
   310       ./bin/test02 --format=db --distance=$distance --run=run-$distance-$trial
       
   311     done
       
   312   done
       
   313 
       
   314 Analysis and Conclusion
       
   315 +++++++++++++++++++++++
       
   316 
       
   317 Once all trials have been conducted, the script executes a simple SQL query over the database using the sqlite3 command line program.  The query computes average packet loss in each set of trials associated with each distance.  It does not take into account different strategies, but the information is present in the database to make some simple extensions and do so.  The collected data is then passed to GNUPlot for graphing.
       
   318   
       
   319 ::
       
   320 
       
   321   CMD="select exp.input,avg(100-((rx.value*100)/tx.value)) \
       
   322       from Singletons rx, Singletons tx, Experiments exp \
       
   323       where rx.run = tx.run AND \
       
   324             rx.run = exp.run AND \
       
   325             rx.name='receiver-rx-packets' AND \
       
   326             tx.name='sender-tx-packets' \
       
   327       group by exp.input \
       
   328       order by abs(exp.input) ASC;"
       
   329   
       
   330   sqlite3 -noheader data.db "$CMD" > wifi-default.data
       
   331   sed -i "s/|/   /" wifi-default.data
       
   332   gnuplot wifi-example.gnuplot
       
   333 
       
   334 The GNUPlot script found at ``examples/stats/wifi-example.gnuplot`` simply defines the output format and some basic formatting for the graph.
       
   335   
       
   336 ::
       
   337 
       
   338   set terminal postscript portrait enhanced lw 2 "Helvetica" 14
       
   339   
       
   340   set size 1.0, 0.66
       
   341   
       
   342   #-------------------------------------------------------
       
   343   set out "wifi-default.eps"
       
   344   #set title "Packet Loss Over Distance"
       
   345   set xlabel "Distance (m) --- average of 5 trials per point"
       
   346   set xrange [0:200]
       
   347   set ylabel "% Packet Loss"
       
   348   set yrange [0:110]
       
   349   
       
   350   plot "wifi-default.data" with lines title "WiFi Defaults"
       
   351 
       
   352 End Result
       
   353 ==========
       
   354 
       
   355 The resulting graph provides no evidence that the default WiFi model's performance is necessarily unreasonable and lends some confidence to an at least token faithfulness to reality.  More importantly, this simple investigation has been carried all the way through using the statistical framework.  Success!
       
   356 
       
   357 .. image:: figures/Wifi-default.png
       
   358 
       
   359