A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
bench-packets.cc
Go to the documentation of this file.
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/command-line.h"
21 #include "ns3/system-wall-clock-ms.h"
22 #include "ns3/packet.h"
23 #include "ns3/packet-metadata.h"
24 #include <iostream>
25 #include <sstream>
26 #include <string>
27 #include <stdlib.h> // for exit ()
28 #include <limits>
29 #include <algorithm>
30 
31 using namespace ns3;
32 
33 template <int N>
34 class BenchHeader : public Header
35 {
36 public:
37  BenchHeader ();
38  bool IsOk (void) const;
39 
44  static TypeId GetTypeId (void);
45  virtual TypeId GetInstanceTypeId (void) const;
46  virtual void Print (std::ostream &os) const;
47  virtual uint32_t GetSerializedSize (void) const;
48  virtual void Serialize (Buffer::Iterator start) const;
49  virtual uint32_t Deserialize (Buffer::Iterator start);
50 private:
51  static std::string GetTypeName (void);
52  bool m_ok;
53 };
54 
55 template <int N>
57  : m_ok (false)
58 {}
59 
60 template <int N>
61 bool
63 {
64  return m_ok;
65 }
66 
67 template <int N>
68 std::string
70 {
71  std::ostringstream oss;
72  oss << "ns3::BenchHeader<" << N << ">";
73  return oss.str ();
74 }
75 
76 template <int N>
77 TypeId
79 {
80  static TypeId tid = TypeId (GetTypeName ().c_str ())
81  .SetParent<Header> ()
82  .SetGroupName ("Utils")
83  .HideFromDocumentation ()
84  .AddConstructor<BenchHeader <N> > ()
85  ;
86  return tid;
87 }
88 template <int N>
89 TypeId
91 {
92  return GetTypeId ();
93 }
94 
95 template <int N>
96 void
97 BenchHeader<N>::Print (std::ostream &os) const
98 {
99  NS_ASSERT (false);
100 }
101 template <int N>
102 uint32_t
104 {
105  return N;
106 }
107 template <int N>
108 void
110 {
111  start.WriteU8 (N, N);
112 }
113 template <int N>
114 uint32_t
116 {
117  m_ok = true;
118  for (int i = 0; i < N; i++)
119  {
120  if (start.ReadU8 () != N)
121  {
122  m_ok = false;
123  }
124  }
125  return N;
126 }
127 
128 template <int N>
129 class BenchTag : public Tag
130 {
131 public:
132  static std::string GetName (void) {
133  std::ostringstream oss;
134  oss << "anon::BenchTag<" << N << ">";
135  return oss.str ();
136  }
141  static TypeId GetTypeId (void) {
142  static TypeId tid = TypeId (GetName ().c_str ())
143  .SetParent<Tag> ()
144  .SetGroupName ("Utils")
145  .HideFromDocumentation ()
146  .AddConstructor<BenchTag<N> > ()
147  ;
148  return tid;
149  }
150  virtual TypeId GetInstanceTypeId (void) const {
151  return GetTypeId ();
152  }
153  virtual uint32_t GetSerializedSize (void) const {
154  return N;
155  }
156  virtual void Serialize (TagBuffer buf) const {
157  for (uint32_t i = 0; i < N; ++i)
158  {
159  buf.WriteU8 (N);
160  }
161  }
162  virtual void Deserialize (TagBuffer buf) {
163  for (uint32_t i = 0; i < N; ++i)
164  {
165  buf.ReadU8 ();
166  }
167  }
168  virtual void Print (std::ostream &os) const {
169  os << "N=" << N;
170  }
172  : Tag () {}
173 };
174 
175 
176 static void
177 benchD (uint32_t n)
178 {
179  BenchHeader<25> ipv4;
180  BenchHeader<8> udp;
181  BenchTag<16> tag1;
182  BenchTag<17> tag2;
183 
184  for (uint32_t i = 0; i < n; i++) {
185  Ptr<Packet> p = Create<Packet> (2000);
186  p->AddPacketTag (tag1);
187  p->AddHeader (udp);
188  p->RemovePacketTag (tag1);
189  p->AddPacketTag (tag2);
190  p->AddHeader (ipv4);
191  Ptr<Packet> o = p->Copy ();
192  o->RemoveHeader (ipv4);
193  p->RemovePacketTag (tag2);
194  o->RemoveHeader (udp);
195  }
196 }
197 
198 
199 
200 static void
201 benchA (uint32_t n)
202 {
203  BenchHeader<25> ipv4;
204  BenchHeader<8> udp;
205 
206  for (uint32_t i = 0; i < n; i++) {
207  Ptr<Packet> p = Create<Packet> (2000);
208  p->AddHeader (udp);
209  p->AddHeader (ipv4);
210  Ptr<Packet> o = p->Copy ();
211  o->RemoveHeader (ipv4);
212  o->RemoveHeader (udp);
213  }
214 }
215 
216 static void
217 benchB (uint32_t n)
218 {
219  BenchHeader<25> ipv4;
220  BenchHeader<8> udp;
221 
222  for (uint32_t i = 0; i < n; i++) {
223  Ptr<Packet> p = Create<Packet> (2000);
224  p->AddHeader (udp);
225  p->AddHeader (ipv4);
226  }
227 }
228 
229 static void
231 {
232  BenchHeader<8> udp;
233 
234  p->RemoveHeader (udp);
235 }
236 
237 static void
239 {
240  BenchHeader<25> ipv4;
241  p->RemoveHeader (ipv4);
242  C2 (p);
243 }
244 
245 static void
246 benchC (uint32_t n)
247 {
248  BenchHeader<25> ipv4;
249  BenchHeader<8> udp;
250 
251  for (uint32_t i = 0; i < n; i++) {
252  Ptr<Packet> p = Create<Packet> (2000);
253  p->AddHeader (udp);
254  p->AddHeader (ipv4);
255  C1 (p);
256  }
257 }
258 
259 static void
260 benchFragment (uint32_t n)
261 {
262  BenchHeader<25> ipv4;
263  BenchHeader<8> udp;
264 
265  for (uint32_t i= 0; i < n; i++) {
266  Ptr<Packet> p = Create<Packet> (2000);
267  p->AddHeader (udp);
268  p->AddHeader (ipv4);
269 
270  Ptr<Packet> frag0 = p->CreateFragment (0, 250);
271  Ptr<Packet> frag1 = p->CreateFragment (250, 250);
272  Ptr<Packet> frag2 = p->CreateFragment (500, 500);
273  Ptr<Packet> frag3 = p->CreateFragment (1000, 500);
274  Ptr<Packet> frag4 = p->CreateFragment (1500, 500);
275 
276  /* Mix fragments in different order */
277  frag2->AddAtEnd (frag3);
278  frag4->AddAtEnd (frag1);
279  frag2->AddAtEnd (frag4);
280  frag0->AddAtEnd (frag2);
281 
282  frag0->RemoveHeader (ipv4);
283  frag0->RemoveHeader (udp);
284  }
285 }
286 
287 static void
288 benchByteTags (uint32_t n)
289 {
290  for (uint32_t i = 0; i < n; i++)
291  {
292  Ptr<Packet> p = Create<Packet> (2000);
293  for (uint32_t j = 0; j < 100; j++)
294  {
295  BenchTag<0> tag;
296  p->AddByteTag (tag);
297  }
298  Ptr<Packet> q = Create<Packet> (1000);
299 
300  // This should trigger adjustment of all byte tags
301  q->AddAtEnd (p);
302  }
303 }
304 
305 static uint64_t
306 runBenchOneIteration (void (*bench) (uint32_t), uint32_t n)
307 {
308  SystemWallClockMs time;
309  time.Start ();
310  (*bench) (n);
311  uint64_t deltaMs = time.End ();
312  return deltaMs;
313 }
314 
315 
316 static void
317 runBench (void (*bench) (uint32_t), uint32_t n, uint32_t minIterations, char const *name)
318 {
319  uint64_t minDelay = std::numeric_limits<uint64_t>::max();
320  for (uint32_t i = 0; i < minIterations; i++)
321  {
322  uint64_t delay = runBenchOneIteration(bench, n);
323  minDelay = std::min(minDelay, delay);
324  }
325  double ps = n;
326  ps *= 1000;
327  ps /= minDelay;
328  std::cout << ps << " packets/s"
329  << " (" << minDelay << " ms elapsed)\t"
330  << name
331  << std::endl;
332 }
333 
334 int main (int argc, char *argv[])
335 {
336  uint32_t n = 0;
337  uint32_t minIterations = 1;
338  bool enablePrinting = false;
339 
341  cmd.Usage ("Benchmark Packet class");
342  cmd.AddValue ("n", "number of iterations", n);
343  cmd.AddValue ("min-iterations", "number of subiterations to minimize iteration time over", minIterations);
344  cmd.AddValue ("enable-printing", "enable packet printing", enablePrinting);
345  cmd.Parse (argc, argv);
346 
347  if (n == 0)
348  {
349  std::cerr << "Error-- number of packets must be specified " <<
350  "by command-line argument --n=(number of packets)" << std::endl;
351  exit (1);
352  }
353  std::cout << "Running bench-packets with n=" << n << std::endl;
354  std::cout << "All tests begin by adding UDP and IPv4 headers." << std::endl;
355 
356  runBench (&benchA, n, minIterations, "Copy packet, remove headers");
357  runBench (&benchB, n, minIterations, "Just add headers");
358  runBench (&benchC, n, minIterations, "Remove by func call");
359  runBench (&benchD, n, minIterations, "Intermixed add/remove headers and tags");
360  runBench (&benchFragment, n, minIterations, "Fragmentation and concatenation");
361  runBench (&benchByteTags, n, minIterations, "Benchmark byte tags");
362 
363  return 0;
364 }
Protocol header serialization and deserialization.
Definition: header.h:42
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
static void C1(Ptr< Packet > p)
virtual void Print(std::ostream &os) const
#define min(a, b)
Definition: 80211b.c:44
virtual void Serialize(Buffer::Iterator start) const
static void benchFragment(uint32_t n)
static void benchByteTags(uint32_t n)
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:824
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
virtual uint32_t Deserialize(Buffer::Iterator start)
static std::string GetName(void)
static std::string GetTypeName(void)
tuple cmd
Definition: second.py:35
TAG_BUFFER_INLINE uint8_t ReadU8(void)
Definition: tag-buffer.h:195
iterator in a Buffer instance
Definition: buffer.h:98
void Usage(const std::string usage)
Supply the program usage and documentation.
Definition: command-line.cc:95
virtual uint32_t GetSerializedSize(void) const
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
Definition: packet.cc:228
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:313
Measure elapsed wall clock time in milliseconds.
#define max(a, b)
Definition: 80211b.c:45
static void benchA(uint32_t n)
virtual uint32_t GetSerializedSize(void) const
void Start(void)
Start a measure.
static uint64_t runBenchOneIteration(void(*bench)(uint32_t), uint32_t n)
static void benchD(uint32_t n)
Parse command-line arguments.
Definition: command-line.h:201
static void benchB(uint32_t n)
static TypeId GetTypeId(void)
Register this type.
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:122
tag a set of bytes in a packet
Definition: tag.h:36
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
virtual void Serialize(TagBuffer buf) const
TAG_BUFFER_INLINE void WriteU8(uint8_t v)
Definition: tag-buffer.h:172
static TypeId GetTypeId(void)
Register this type.
static void runBench(void(*bench)(uint32_t), uint32_t n, uint32_t minIterations, char const *name)
read and write tag data
Definition: tag-buffer.h:51
void WriteU8(uint8_t data)
Definition: buffer.h:863
void AddValue(const std::string &name, const std::string &help, T &value)
Add a program argument, assigning to POD.
Definition: command-line.h:491
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:831
virtual void Print(std::ostream &os) const
uint8_t ReadU8(void)
Definition: buffer.h:1015
void Parse(int argc, char *argv[])
Parse the program arguments.
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
static void C2(Ptr< Packet > p)
static void benchC(uint32_t n)
int64_t End(void)
Stop measuring the time since Start() was called.
bool IsOk(void) const
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:827
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:257
void AddByteTag(const Tag &tag) const
Tag each byte included in this packet with a new byte tag.
Definition: packet.cc:791
virtual void Deserialize(TagBuffer buf)