A Discrete-Event Network Simulator
API
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)
def start()
Definition: core.py:1482
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:96
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:205
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.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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:868
void AddValue(const std::string &name, const std::string &help, T &value)
Add a program argument, assigning to POD.
Definition: command-line.h:495
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:1020
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:904
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)