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
mathieu@150
     1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
mathieu@12
     2
/*
mathieu@12
     3
 * Copyright (c) 2006 INRIA
mathieu@12
     4
 *
mathieu@12
     5
 * This program is free software; you can redistribute it and/or modify
mathieu@12
     6
 * it under the terms of the GNU General Public License version 2 as
mathieu@12
     7
 * published by the Free Software Foundation;
mathieu@12
     8
 *
mathieu@12
     9
 * This program is distributed in the hope that it will be useful,
mathieu@12
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
mathieu@12
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
mathieu@12
    12
 * GNU General Public License for more details.
mathieu@12
    13
 *
mathieu@12
    14
 * You should have received a copy of the GNU General Public License
mathieu@12
    15
 * along with this program; if not, write to the Free Software
mathieu@12
    16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
mathieu@12
    17
 *
mathieu@12
    18
 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
mathieu@12
    19
 */
mathieu@832
    20
#include "ns3/system-wall-clock-ms.h"
mathieu@14
    21
#include "ns3/packet.h"
mathieu@882
    22
#include "ns3/packet-metadata.h"
mathieu@12
    23
#include <iostream>
mathieu@832
    24
#include <sstream>
mathieu@3051
    25
#include <string>
mathieu@3365
    26
#include <stdlib.h> // for exit ()
mathieu@12
    27
mathieu@16
    28
using namespace ns3;
mathieu@12
    29
mathieu@832
    30
template <int N>
mathieu@832
    31
class BenchHeader : public Header
mathieu@832
    32
{
mathieu@832
    33
public:
mathieu@832
    34
  BenchHeader ();
mathieu@832
    35
  bool IsOk (void) const;
mathieu@1322
    36
mathieu@2643
    37
  static TypeId GetTypeId (void);
mathieu@2643
    38
  virtual TypeId GetInstanceTypeId (void) const;
mathieu@2646
    39
  virtual void Print (std::ostream &os) const;
mathieu@2643
    40
  virtual uint32_t GetSerializedSize (void) const;
mathieu@2643
    41
  virtual void Serialize (Buffer::Iterator start) const;
mathieu@2643
    42
  virtual uint32_t Deserialize (Buffer::Iterator start);
mathieu@832
    43
private:
mathieu@3051
    44
  static std::string GetTypeName (void);
mathieu@832
    45
  bool m_ok;
mathieu@832
    46
};
mathieu@832
    47
mathieu@832
    48
template <int N>
mathieu@832
    49
BenchHeader<N>::BenchHeader ()
mathieu@832
    50
  : m_ok (false)
mathieu@832
    51
{}
mathieu@832
    52
mathieu@832
    53
template <int N>
mathieu@832
    54
bool 
mathieu@832
    55
BenchHeader<N>::IsOk (void) const
mathieu@832
    56
{
mathieu@832
    57
  return m_ok;
mathieu@832
    58
}
mathieu@832
    59
mathieu@832
    60
template <int N>
mathieu@3051
    61
std::string 
mathieu@3051
    62
BenchHeader<N>::GetTypeName (void)
mathieu@3051
    63
{
mathieu@3051
    64
  std::ostringstream oss;
mathieu@3051
    65
  oss << "ns3::BenchHeader<" << N << ">";
mathieu@3051
    66
  return oss.str ();
mathieu@3051
    67
}
mathieu@3051
    68
mathieu@3051
    69
template <int N>
mathieu@2643
    70
TypeId 
mathieu@2643
    71
BenchHeader<N>::GetTypeId (void)
mathieu@2643
    72
{
mathieu@3051
    73
  static TypeId tid = TypeId (GetTypeName ().c_str ())
mathieu@2643
    74
    .SetParent<Header> ()
mathieu@2643
    75
    ;
mathieu@2643
    76
  return tid;
mathieu@2643
    77
}
mathieu@2643
    78
template <int N>
mathieu@2643
    79
TypeId 
mathieu@2643
    80
BenchHeader<N>::GetInstanceTypeId (void) const
mathieu@2643
    81
{
mathieu@2643
    82
  return GetTypeId ();
mathieu@2643
    83
}
mathieu@2643
    84
mathieu@2643
    85
template <int N>
mathieu@832
    86
void 
mathieu@1322
    87
BenchHeader<N>::Print (std::ostream &os) const
mathieu@832
    88
{
mathieu@832
    89
  NS_ASSERT (false);
mathieu@832
    90
}
mathieu@832
    91
template <int N>
mathieu@832
    92
uint32_t 
mathieu@832
    93
BenchHeader<N>::GetSerializedSize (void) const
mathieu@832
    94
{
mathieu@832
    95
  return N;
mathieu@832
    96
}
mathieu@832
    97
template <int N>
mathieu@832
    98
void 
mathieu@1322
    99
BenchHeader<N>::Serialize (Buffer::Iterator start) const
mathieu@832
   100
{
mathieu@832
   101
  start.WriteU8 (N, N);
mathieu@832
   102
}
mathieu@832
   103
template <int N>
mathieu@832
   104
uint32_t
mathieu@1322
   105
BenchHeader<N>::Deserialize (Buffer::Iterator start)
mathieu@832
   106
{
mathieu@832
   107
  m_ok = true;
mathieu@832
   108
  for (int i = 0; i < N; i++)
mathieu@832
   109
    {
mathieu@832
   110
      if (start.ReadU8 () != N)
mathieu@832
   111
        {
mathieu@832
   112
          m_ok = false;
mathieu@832
   113
        }
mathieu@832
   114
    }
mathieu@832
   115
  return N;
mathieu@832
   116
}
mathieu@832
   117
mathieu@3058
   118
template <int N>
mathieu@3058
   119
class BenchTag : public Tag
mathieu@3058
   120
{
mathieu@3058
   121
public:
mathieu@3058
   122
  static std::string GetName (void) {
mathieu@3058
   123
    std::ostringstream oss;
mathieu@3058
   124
    oss << "anon::BenchTag<" << N << ">";
mathieu@3058
   125
    return oss.str ();
mathieu@3058
   126
  }
mathieu@3058
   127
  static TypeId GetTypeId (void) {
mathieu@3058
   128
    static TypeId tid = TypeId (GetName ().c_str ())
mathieu@3058
   129
      .SetParent<Tag> ()
mathieu@3058
   130
      .AddConstructor<BenchTag > ()
mathieu@3058
   131
      .HideFromDocumentation ()
mathieu@3058
   132
      ;
mathieu@3058
   133
    return tid;
mathieu@3058
   134
  }
mathieu@3058
   135
  virtual TypeId GetInstanceTypeId (void) const {
mathieu@3058
   136
    return GetTypeId ();
mathieu@3058
   137
  }
mathieu@3058
   138
  virtual uint32_t GetSerializedSize (void) const {
mathieu@3058
   139
    return N;
mathieu@3058
   140
  }
mathieu@3058
   141
  virtual void Serialize (TagBuffer buf) const {
mathieu@3058
   142
    for (uint32_t i = 0; i < N; ++i)
mathieu@3058
   143
      {
mathieu@3058
   144
        buf.WriteU8 (N);
mathieu@3058
   145
      }
mathieu@3058
   146
  }
mathieu@3058
   147
  virtual void Deserialize (TagBuffer buf) {
mathieu@3058
   148
    for (uint32_t i = 0; i < N; ++i)
mathieu@3058
   149
      {
mathieu@3058
   150
        buf.ReadU8 ();
mathieu@3058
   151
      }
mathieu@3058
   152
  }
mathieu@3208
   153
  virtual void Print (std::ostream &os) const {
mathieu@3208
   154
    os << "N=" << N;
mathieu@3208
   155
  }
mathieu@3058
   156
  BenchTag ()
mathieu@3058
   157
    : Tag () {}
mathieu@3058
   158
};
mathieu@832
   159
mathieu@832
   160
mathieu@12
   161
static void 
mathieu@3058
   162
benchD (uint32_t n)
mathieu@3058
   163
{
mathieu@3058
   164
  BenchHeader<25> ipv4;
mathieu@3058
   165
  BenchHeader<8> udp;
mathieu@3058
   166
  BenchTag<16> tag1;
mathieu@3058
   167
  BenchTag<17> tag2;
mathieu@3058
   168
mathieu@3058
   169
  for (uint32_t i = 0; i < n; i++) {
mathieu@3058
   170
    Ptr<Packet> p = Create<Packet> (2000);
mathieu@4502
   171
    p->AddPacketTag (tag1);
mathieu@3058
   172
    p->AddHeader (udp);
mathieu@4502
   173
    p->RemovePacketTag (tag1);
mathieu@4502
   174
    p->AddPacketTag (tag2);
mathieu@3058
   175
    p->AddHeader (ipv4);
mathieu@3058
   176
    Ptr<Packet> o = p->Copy ();
mathieu@3058
   177
    o->RemoveHeader (ipv4);
mathieu@4502
   178
    p->RemovePacketTag (tag2);
mathieu@3058
   179
    o->RemoveHeader (udp);
mathieu@3058
   180
  }
mathieu@3058
   181
}
mathieu@3058
   182
mathieu@3058
   183
mathieu@3058
   184
mathieu@3058
   185
static void 
mathieu@3058
   186
benchA (uint32_t n)
mathieu@12
   187
{
mathieu@832
   188
  BenchHeader<25> ipv4;
mathieu@832
   189
  BenchHeader<8> udp;
mathieu@12
   190
mathieu@150
   191
  for (uint32_t i = 0; i < n; i++) {
mathieu@1866
   192
    Ptr<Packet> p = Create<Packet> (2000);
mathieu@1866
   193
    p->AddHeader (udp);
mathieu@1866
   194
    p->AddHeader (ipv4);
mathieu@1866
   195
    Ptr<Packet> o = p->Copy ();
mathieu@1866
   196
    o->RemoveHeader (ipv4);
mathieu@1866
   197
    o->RemoveHeader (udp);
mathieu@150
   198
  }
mathieu@12
   199
}
mathieu@12
   200
mathieu@12
   201
static void 
mathieu@3058
   202
benchB (uint32_t n)
mathieu@12
   203
{
mathieu@832
   204
  BenchHeader<25> ipv4;
mathieu@832
   205
  BenchHeader<8> udp;
mathieu@12
   206
mathieu@150
   207
  for (uint32_t i = 0; i < n; i++) {
mathieu@1866
   208
    Ptr<Packet> p = Create<Packet> (2000);
mathieu@1866
   209
    p->AddHeader (udp);
mathieu@1866
   210
    p->AddHeader (ipv4);
mathieu@150
   211
  }
mathieu@12
   212
}
mathieu@12
   213
mathieu@12
   214
static void
mathieu@3058
   215
C2 (Ptr<Packet> p)
mathieu@12
   216
{
mathieu@832
   217
  BenchHeader<8> udp;
mathieu@12
   218
mathieu@1866
   219
  p->RemoveHeader (udp);
mathieu@12
   220
}
mathieu@12
   221
mathieu@12
   222
static void 
mathieu@3058
   223
C1 (Ptr<Packet> p)
mathieu@12
   224
{
mathieu@832
   225
  BenchHeader<25> ipv4;
mathieu@1866
   226
  p->RemoveHeader (ipv4);
mathieu@3058
   227
  C2 (p);
mathieu@12
   228
}
mathieu@12
   229
mathieu@12
   230
static void
mathieu@3058
   231
benchC (uint32_t n)
mathieu@12
   232
{
mathieu@832
   233
  BenchHeader<25> ipv4;
mathieu@832
   234
  BenchHeader<8> udp;
mathieu@12
   235
mathieu@150
   236
  for (uint32_t i = 0; i < n; i++) {
mathieu@1866
   237
    Ptr<Packet> p = Create<Packet> (2000);
mathieu@1866
   238
    p->AddHeader (udp);
mathieu@1866
   239
    p->AddHeader (ipv4);
mathieu@3058
   240
    C1 (p);
mathieu@150
   241
  }
mathieu@12
   242
}
mathieu@12
   243
mathieu@12
   244
mathieu@12
   245
static void
mathieu@53
   246
runBench (void (*bench) (uint32_t), uint32_t n, char const *name)
mathieu@12
   247
{
mathieu@832
   248
  SystemWallClockMs time;
mathieu@832
   249
  time.Start ();
mathieu@150
   250
  (*bench) (n);
craigdo@5458
   251
  uint64_t deltaMs = time.End ();
mathieu@150
   252
  double ps = n;
mathieu@150
   253
  ps *= 1000;
mathieu@150
   254
  ps /= deltaMs;
mathieu@150
   255
  std::cout << name<<"=" << ps << " packets/s" << std::endl;
mathieu@12
   256
}
mathieu@12
   257
mathieu@12
   258
int main (int argc, char *argv[])
mathieu@12
   259
{
mathieu@150
   260
  uint32_t n = 0;
mathieu@150
   261
  while (argc > 0) {
mathieu@833
   262
      if (strncmp ("--n=", argv[0],strlen ("--n=")) == 0) 
mathieu@833
   263
        {
mathieu@150
   264
          char const *nAscii = argv[0] + strlen ("--n=");
mathieu@3365
   265
          std::istringstream iss;
mathieu@3365
   266
          iss.str (nAscii);
mathieu@3365
   267
          iss >> n;
mathieu@833
   268
        }
mathieu@3750
   269
      if (strncmp ("--enable-printing", argv[0], strlen ("--enable-printing")) == 0)
mathieu@3750
   270
        {
mathieu@3750
   271
          Packet::EnablePrinting ();
mathieu@3750
   272
        }
mathieu@150
   273
      argc--;
mathieu@150
   274
      argv++;
mathieu@150
   275
  }
tomh@1814
   276
  if (n == 0)
tomh@1814
   277
    {
tomh@1814
   278
      std::cerr << "Error-- number of packets must be specified " <<
tomh@1814
   279
        "by command-line argument --n=(number of packets)" << std::endl;
tomh@1814
   280
      exit (1);
tomh@1814
   281
    }
tomh@1814
   282
  std::cout << "Running bench-packets with n=" << n << std::endl;
mathieu@12
   283
mathieu@3058
   284
  runBench (&benchA, n, "a");
mathieu@3058
   285
  runBench (&benchB, n, "b");
mathieu@3058
   286
  runBench (&benchC, n, "c");
mathieu@3058
   287
  runBench (&benchD, n, "d");
mathieu@894
   288
mathieu@150
   289
  return 0;
mathieu@12
   290
}