utils/bench-packets.cc
author Josh Pelkey <jpelkey@gatech.edu>
Wed, 11 Aug 2010 11:37:37 -0400
changeset 6553 fb5ad9c7755a
parent 4502 07d34c0d8d18
permissions -rw-r--r--
update release notes and fix doxygen warnings
     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 #include "ns3/system-wall-clock-ms.h"
    21 #include "ns3/packet.h"
    22 #include "ns3/packet-metadata.h"
    23 #include <iostream>
    24 #include <sstream>
    25 #include <string>
    26 #include <stdlib.h> // for exit ()
    27 
    28 using namespace ns3;
    29 
    30 template <int N>
    31 class BenchHeader : public Header
    32 {
    33 public:
    34   BenchHeader ();
    35   bool IsOk (void) const;
    36 
    37   static TypeId GetTypeId (void);
    38   virtual TypeId GetInstanceTypeId (void) const;
    39   virtual void Print (std::ostream &os) const;
    40   virtual uint32_t GetSerializedSize (void) const;
    41   virtual void Serialize (Buffer::Iterator start) const;
    42   virtual uint32_t Deserialize (Buffer::Iterator start);
    43 private:
    44   static std::string GetTypeName (void);
    45   bool m_ok;
    46 };
    47 
    48 template <int N>
    49 BenchHeader<N>::BenchHeader ()
    50   : m_ok (false)
    51 {}
    52 
    53 template <int N>
    54 bool 
    55 BenchHeader<N>::IsOk (void) const
    56 {
    57   return m_ok;
    58 }
    59 
    60 template <int N>
    61 std::string 
    62 BenchHeader<N>::GetTypeName (void)
    63 {
    64   std::ostringstream oss;
    65   oss << "ns3::BenchHeader<" << N << ">";
    66   return oss.str ();
    67 }
    68 
    69 template <int N>
    70 TypeId 
    71 BenchHeader<N>::GetTypeId (void)
    72 {
    73   static TypeId tid = TypeId (GetTypeName ().c_str ())
    74     .SetParent<Header> ()
    75     ;
    76   return tid;
    77 }
    78 template <int N>
    79 TypeId 
    80 BenchHeader<N>::GetInstanceTypeId (void) const
    81 {
    82   return GetTypeId ();
    83 }
    84 
    85 template <int N>
    86 void 
    87 BenchHeader<N>::Print (std::ostream &os) const
    88 {
    89   NS_ASSERT (false);
    90 }
    91 template <int N>
    92 uint32_t 
    93 BenchHeader<N>::GetSerializedSize (void) const
    94 {
    95   return N;
    96 }
    97 template <int N>
    98 void 
    99 BenchHeader<N>::Serialize (Buffer::Iterator start) const
   100 {
   101   start.WriteU8 (N, N);
   102 }
   103 template <int N>
   104 uint32_t
   105 BenchHeader<N>::Deserialize (Buffer::Iterator start)
   106 {
   107   m_ok = true;
   108   for (int i = 0; i < N; i++)
   109     {
   110       if (start.ReadU8 () != N)
   111         {
   112           m_ok = false;
   113         }
   114     }
   115   return N;
   116 }
   117 
   118 template <int N>
   119 class BenchTag : public Tag
   120 {
   121 public:
   122   static std::string GetName (void) {
   123     std::ostringstream oss;
   124     oss << "anon::BenchTag<" << N << ">";
   125     return oss.str ();
   126   }
   127   static TypeId GetTypeId (void) {
   128     static TypeId tid = TypeId (GetName ().c_str ())
   129       .SetParent<Tag> ()
   130       .AddConstructor<BenchTag > ()
   131       .HideFromDocumentation ()
   132       ;
   133     return tid;
   134   }
   135   virtual TypeId GetInstanceTypeId (void) const {
   136     return GetTypeId ();
   137   }
   138   virtual uint32_t GetSerializedSize (void) const {
   139     return N;
   140   }
   141   virtual void Serialize (TagBuffer buf) const {
   142     for (uint32_t i = 0; i < N; ++i)
   143       {
   144         buf.WriteU8 (N);
   145       }
   146   }
   147   virtual void Deserialize (TagBuffer buf) {
   148     for (uint32_t i = 0; i < N; ++i)
   149       {
   150         buf.ReadU8 ();
   151       }
   152   }
   153   virtual void Print (std::ostream &os) const {
   154     os << "N=" << N;
   155   }
   156   BenchTag ()
   157     : Tag () {}
   158 };
   159 
   160 
   161 static void 
   162 benchD (uint32_t n)
   163 {
   164   BenchHeader<25> ipv4;
   165   BenchHeader<8> udp;
   166   BenchTag<16> tag1;
   167   BenchTag<17> tag2;
   168 
   169   for (uint32_t i = 0; i < n; i++) {
   170     Ptr<Packet> p = Create<Packet> (2000);
   171     p->AddPacketTag (tag1);
   172     p->AddHeader (udp);
   173     p->RemovePacketTag (tag1);
   174     p->AddPacketTag (tag2);
   175     p->AddHeader (ipv4);
   176     Ptr<Packet> o = p->Copy ();
   177     o->RemoveHeader (ipv4);
   178     p->RemovePacketTag (tag2);
   179     o->RemoveHeader (udp);
   180   }
   181 }
   182 
   183 
   184 
   185 static void 
   186 benchA (uint32_t n)
   187 {
   188   BenchHeader<25> ipv4;
   189   BenchHeader<8> udp;
   190 
   191   for (uint32_t i = 0; i < n; i++) {
   192     Ptr<Packet> p = Create<Packet> (2000);
   193     p->AddHeader (udp);
   194     p->AddHeader (ipv4);
   195     Ptr<Packet> o = p->Copy ();
   196     o->RemoveHeader (ipv4);
   197     o->RemoveHeader (udp);
   198   }
   199 }
   200 
   201 static void 
   202 benchB (uint32_t n)
   203 {
   204   BenchHeader<25> ipv4;
   205   BenchHeader<8> udp;
   206 
   207   for (uint32_t i = 0; i < n; i++) {
   208     Ptr<Packet> p = Create<Packet> (2000);
   209     p->AddHeader (udp);
   210     p->AddHeader (ipv4);
   211   }
   212 }
   213 
   214 static void
   215 C2 (Ptr<Packet> p)
   216 {
   217   BenchHeader<8> udp;
   218 
   219   p->RemoveHeader (udp);
   220 }
   221 
   222 static void 
   223 C1 (Ptr<Packet> p)
   224 {
   225   BenchHeader<25> ipv4;
   226   p->RemoveHeader (ipv4);
   227   C2 (p);
   228 }
   229 
   230 static void
   231 benchC (uint32_t n)
   232 {
   233   BenchHeader<25> ipv4;
   234   BenchHeader<8> udp;
   235 
   236   for (uint32_t i = 0; i < n; i++) {
   237     Ptr<Packet> p = Create<Packet> (2000);
   238     p->AddHeader (udp);
   239     p->AddHeader (ipv4);
   240     C1 (p);
   241   }
   242 }
   243 
   244 
   245 static void
   246 runBench (void (*bench) (uint32_t), uint32_t n, char const *name)
   247 {
   248   SystemWallClockMs time;
   249   time.Start ();
   250   (*bench) (n);
   251   uint64_t deltaMs = time.End ();
   252   double ps = n;
   253   ps *= 1000;
   254   ps /= deltaMs;
   255   std::cout << name<<"=" << ps << " packets/s" << std::endl;
   256 }
   257 
   258 int main (int argc, char *argv[])
   259 {
   260   uint32_t n = 0;
   261   while (argc > 0) {
   262       if (strncmp ("--n=", argv[0],strlen ("--n=")) == 0) 
   263         {
   264           char const *nAscii = argv[0] + strlen ("--n=");
   265           std::istringstream iss;
   266           iss.str (nAscii);
   267           iss >> n;
   268         }
   269       if (strncmp ("--enable-printing", argv[0], strlen ("--enable-printing")) == 0)
   270         {
   271           Packet::EnablePrinting ();
   272         }
   273       argc--;
   274       argv++;
   275   }
   276   if (n == 0)
   277     {
   278       std::cerr << "Error-- number of packets must be specified " <<
   279         "by command-line argument --n=(number of packets)" << std::endl;
   280       exit (1);
   281     }
   282   std::cout << "Running bench-packets with n=" << n << std::endl;
   283 
   284   runBench (&benchA, n, "a");
   285   runBench (&benchB, n, "b");
   286   runBench (&benchC, n, "c");
   287   runBench (&benchD, n, "d");
   288 
   289   return 0;
   290 }