blob: da2f334bacb81aa382dee70d0dc9acb899a018bc [file] [log] [blame]
Spyridon Mastorakisb4bd4b72015-01-05 17:41:12 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2011-2015 Regents of the University of California.
4 *
5 * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
6 * contributors.
7 *
8 * ndnSIM is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * ndnSIM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * ndnSIM, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 **/
19
20// ndn-test.cpp
21
22#include "ns3/core-module.h"
23#include "ns3/network-module.h"
24#include "ns3/point-to-point-module.h"
25#include "ns3/ndnSIM-module.h"
26
27#include <sys/time.h>
28#include "ns3/ndnSIM/utils/mem-usage.hpp"
29#include "ns3/ndnSIM/model/cs/ndn-content-store.hpp"
30#include "ns3/ndnSIM/utils/mem-usage.hpp"
31
32namespace ns3 {
33
34/**
35 * This scenario simulates a very simple network topology:
36 *
37 *
38 * +----------+ 10000Mbps +----------+
39 * | consumer | <------------> | producer |
40 * +----------+ 10ms +----------+
41 *
42 *
43 * NS_LOG=ndn.Consumer ./waf --run ndn-test
44 */
45
46class Tester {
47public:
48 Tester()
49 : m_csSize(100)
50 , m_interestRate(1000)
51 , m_shouldEvaluatePit(false)
52 , m_simulationTime(Seconds(2000) / m_interestRate)
53 {
54 }
55
56 int
57 run(int argc, char* argv[]);
58
59 void
60 printHeader(std::ostream& os);
61
62 void
63 printStats(std::ostream& os, Time nextPrintTime, double beginRealTime);
64
65private:
66 std::string m_oldContentStore;
67 size_t m_csSize;
68 double m_interestRate;
69 bool m_shouldEvaluatePit;
70 std::string m_strategy;
71 double m_initialOverhead;
72 Time m_simulationTime;
73};
74
75void
76Tester::printHeader(std::ostream& os)
77{
78 m_initialOverhead = MemUsage::Get() / 1024.0 / 1024.0;
79 os << "SimulationTime"
80 << "\t"
81 << "RealTime"
82 << "\t"
83 << "NumberOfInterests (total)"
84 << "\t"
85 << "NumberOfInterests (per real time)"
86 << "\n";
87}
88
89void
90Tester::printStats(std::ostream& os, Time nextPrintTime, double beginRealTime)
91{
92 ::timeval t;
93 gettimeofday(&t, NULL);
94 double realTime = t.tv_sec + (0.000001 * (unsigned)t.tv_usec) - beginRealTime;
95 Time simTime = Simulator::Now();
96
97 os << simTime << "\t";
98 os << realTime << "\t";
99
100 double interestCount = m_interestRate * simTime.ToDouble(Time::S);
101 double nInterestsPerSec = interestCount / realTime;
102
103 os << interestCount << "\t" << nInterestsPerSec << "\t";
104
105 uint64_t pitCount = 0;
106 uint64_t csCount = 0;
107 for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
108
109 auto pitSize = (*node)->GetObject<ndn::L3Protocol>()->getForwarder()->getPit().size();
110 if (pitSize != 0)
111 pitCount += pitSize;
112
113 if (true != true) {
114 Ptr<ndn::ContentStore> cs = (*node)->GetObject<ndn::ContentStore>();
115 if (cs != 0)
116 csCount += cs->GetSize();
117 }
118 else {
119 auto csSize = (*node)->GetObject<ndn::L3Protocol>()->getForwarder()->getCs().size();
120 if (csSize != 0)
121 csCount += csSize;
122 }
123 }
124
125 os << "pit:" << pitCount << "\t";
126 os << "cs:" << csCount << "\t";
127
128 os << MemUsage::Get() / 1024.0 / 1024.0 << "MiB\n";
129
130 if ((simTime + nextPrintTime) >= m_simulationTime) {
131 double finalOverhead = MemUsage::Get() / 1024.0 / 1024.0;
132 if (m_shouldEvaluatePit) {
133 if (pitCount != 0) {
134 os << "Approximate memory overhead per PIT entry:"
135 << 1000 * (finalOverhead - m_initialOverhead) / pitCount << "KiB\n";
136 }
137 else {
138 os << "`The number of PIT entries is equal to zero\n";
139 }
140 }
141 else {
142 if (csCount != 0) {
143 os << "Approximate memory overhead per CS entry:"
144 << 1000 * (finalOverhead - m_initialOverhead) / csCount << "KiB\n";
145 }
146 else {
147 os << "The number of CS entries is equal to zero\n";
148 }
149 }
150 }
151
152 Simulator::Schedule(nextPrintTime, &Tester::printStats, this, ref(os), nextPrintTime,
153 beginRealTime);
154}
155
156int
157Tester::run(int argc, char* argv[])
158{
159 // setting default parameters for PointToPoint links and channels
160 Config::SetDefault("ns3::PointToPointNetDevice::DataRate", StringValue("10000Mbps"));
161 Config::SetDefault("ns3::PointToPointChannel::Delay", StringValue("10ms"));
162 Config::SetDefault("ns3::DropTailQueue::MaxPackets", StringValue("20"));
163
164 // Read optional command-line parameters (e.g., enable visualizer with ./waf --run=<> --visualize
165 CommandLine cmd;
166 cmd.AddValue("old-cs", "Old content store to use "
167 "(e.g., ns3::ndn::cs::Lru, ns3::ndn::cs::Lfu, ...)",
168 m_oldContentStore);
169 cmd.AddValue("cs-size", "Maximum number of cached packets per node", m_csSize);
170 cmd.AddValue("rate", "Interest rate", m_interestRate);
171 cmd.AddValue("pit", "Perform PIT evaluation if this parameter is true",
172 m_shouldEvaluatePit);
173 cmd.AddValue("strategy", "Choose forwarding strategy "
174 "(e.g., /localhost/nfd/strategy/broadcast, "
175 "/localhost/nfd/strategy/best-route, ...) ",
176 m_strategy);
177 cmd.AddValue("sim-time", "Simulation time", m_simulationTime);
178 cmd.Parse(argc, argv);
179
180 // Creating nodes
181 NodeContainer nodes;
182 nodes.Create(2);
183
184 // Connecting nodes using two links
185 PointToPointHelper p2p;
186 p2p.Install(nodes.Get(0), nodes.Get(1));
187
188 // Install NDN stack on all nodes
189 ndn::StackHelper ndnHelper;
190 ndnHelper.setCsSize(m_csSize);
191
192 if (!m_oldContentStore.empty()) {
193 ndnHelper.SetOldContentStore(m_oldContentStore, "MaxSize", std::to_string(m_csSize));
194 }
195
196 ndnHelper.InstallAll();
197
198 ndn::FibHelper::AddRoute(nodes.Get(0), "/", nodes.Get(1), 10);
199 if (!m_strategy.empty()) {
200 ndn::StrategyChoiceHelper::InstallAll("/", m_strategy);
201 }
202
203 // Installing applications
204
205 // Consumer
206 ndn::AppHelper consumerHelper("ns3::ndn::ConsumerCbr");
207 // Consumer will request /prefix/0, /prefix/1, ...
208 consumerHelper.SetPrefix("/prefix");
209 consumerHelper.SetAttribute("Frequency", DoubleValue(m_interestRate));
210 consumerHelper.Install(nodes.Get(0)); // first node
211
212 if (!m_shouldEvaluatePit) {
213 // Producer
214 ndn::AppHelper producerHelper("ns3::ndn::Producer");
215 // Producer will reply to all requests starting with /prefix
216 producerHelper.SetPrefix("/prefix");
217 producerHelper.SetAttribute("PayloadSize", StringValue("1024"));
218 producerHelper.Install(nodes.Get(1)); // last node
219 }
220
221 Simulator::Stop(m_simulationTime);
222
223 struct ::timeval t;
224 gettimeofday(&t, NULL);
225 double beginRealTime = t.tv_sec + (0.000001 * (unsigned)t.tv_usec);
226 Simulator::Schedule(Seconds(0), &Tester::printHeader, this, ref(std::cout));
227 Simulator::Schedule(m_simulationTime / 200, &Tester::printStats, this, ref(std::cout),
228 m_simulationTime / 200, beginRealTime);
229
230 L2RateTracer::InstallAll("drop-trace2.txt", Seconds(0.5));
231 Simulator::Run();
232 Simulator::Destroy();
233
234 return 0;
235}
236
237} // namespace ns3
238
239int
240main(int argc, char* argv[])
241{
242 ns3::Tester tester;
243 return tester.run(argc, argv);
244}