Affichage dans ndnSIM
Bonjour,
J'essaie d'afficher les deux variables ''m-highdata'' et ''m_window'' de la classe ConsumerPcon dans ndnSIM
J'ai utilisé la topologie jointe (ndn-congestion-topo-plugin.cpp), pour obtenir un affichage dans le fichier '' outputFile.txt".
Le problème rencontré est que ndnSIM ne les affiche que pour le premier temps de simulation (time=0 / m_highdata =0 / m_window =0)
Comment puis-je procéder pour obtenir toutes les valeurs durant toute la période de simulation ?
ndn-consumer-pcon.cpp
#include "ndn-consumer-pcon.hpp" #include <iostream> #include <fstream> using namespace std; NS_LOG_COMPONENT_DEFINE("ndn.ConsumerPcon"); namespace ns3 { namespace ndn { NS_OBJECT_ENSURE_REGISTERED(ConsumerPcon); constexpr double ConsumerPcon::CUBIC_C; constexpr uint32_t ConsumerPcon::BIC_MAX_INCREMENT; constexpr uint32_t ConsumerPcon::BIC_LOW_WINDOW; ConsumerPcon consumer ; TypeId ConsumerPcon::GetTypeId() { static TypeId tid = TypeId("ns3::ndn::ConsumerPcon") .SetGroupName("Ndn") .SetParent<ConsumerWindow>() .AddConstructor<ConsumerPcon>() .AddAttribute("CcAlgorithm", "Specify which window adaptation algorithm to use (AIMD, BIC, or CUBIC)", EnumValue(CcAlgorithm::AIMD), MakeEnumAccessor(&ConsumerPcon::m_ccAlgorithm), MakeEnumChecker(CcAlgorithm::AIMD, "AIMD", CcAlgorithm::BIC, "BIC", CcAlgorithm::CUBIC, "CUBIC")) .AddAttribute("Beta", "TCP Multiplicative Decrease factor", DoubleValue(0.5), MakeDoubleAccessor(&ConsumerPcon::m_beta), MakeDoubleChecker<double>()) .AddAttribute("CubicBeta", "TCP CUBIC Multiplicative Decrease factor", DoubleValue(0.8), MakeDoubleAccessor(&ConsumerPcon::m_cubicBeta), MakeDoubleChecker<double>()) .AddAttribute("AddRttSuppress", "Minimum number of RTTs (1 + this factor) between window decreases", DoubleValue(0.5), // This default value was chosen after manual testing MakeDoubleAccessor(&ConsumerPcon::m_addRttSuppress), MakeDoubleChecker<double>()) .AddAttribute("ReactToCongestionMarks", "If true, process received congestion marks", BooleanValue(true), MakeBooleanAccessor(&ConsumerPcon::m_reactToCongestionMarks), MakeBooleanChecker()) .AddAttribute("UseCwa", "If true, use Conservative Window Adaptation", BooleanValue(true), MakeBooleanAccessor(&ConsumerPcon::m_useCwa), MakeBooleanChecker()) .AddAttribute("UseCubicFastConvergence", "If true, use TCP CUBIC Fast Convergence", BooleanValue(false), MakeBooleanAccessor(&ConsumerPcon::m_useCubicFastConv), MakeBooleanChecker()); return tid; } ConsumerPcon::ConsumerPcon() : m_ssthresh(std::numeric_limits<double>::max()) , m_highData(0) , m_recPoint(0.0) , m_cubicWmax(0) , m_cubicLastWmax(0) , m_cubicLastDecrease(time::steady_clock::now()) , m_bicMinWin(0) , m_bicMaxWin(std::numeric_limits<double>::max()) , m_bicTargetWin(0) , m_bicSsCwnd(0) , m_bicSsTarget(0) , m_isBicSs(false) { } void ConsumerPcon::OnData(shared_ptr<const Data> data) { Consumer::OnData(data); uint64_t sequenceNum = data->getName().get(-1).toSequenceNumber(); // Set highest received Data to sequence number if (m_highData < sequenceNum) { m_highData = sequenceNum; } if (data->getCongestionMark() > 0) { if (m_reactToCongestionMarks) { NS_LOG_DEBUG("Received congestion mark: " << data->getCongestionMark()); WindowDecrease(); } else { NS_LOG_DEBUG("Ignored received congestion mark: " << data->getCongestionMark()); } } else { WindowIncrease(); } if (m_inFlight > static_cast<uint32_t>(0)) { m_inFlight--; } NS_LOG_DEBUG("Window: " << m_window << ", InFlight: " << m_inFlight); ScheduleNextPacket(); } void ConsumerPcon::OnTimeout(uint32_t sequenceNum) { WindowDecrease(); if (m_inFlight > static_cast<uint32_t>(0)) { m_inFlight--; } NS_LOG_DEBUG("Window: " << m_window << ", InFlight: " << m_inFlight); Consumer::OnTimeout(sequenceNum); } void ConsumerPcon::WindowIncrease() { if (m_ccAlgorithm == CcAlgorithm::AIMD) { if (m_window < m_ssthresh) { m_window += 1.0; } else { m_window += (1.0 / m_window); } } else if (m_ccAlgorithm == CcAlgorithm::CUBIC) { CubicIncrease(); } else if (m_ccAlgorithm == CcAlgorithm::BIC) { BicIncrease(); } else { BOOST_ASSERT_MSG(false, "Unknown CC Algorithm"); } NS_LOG_DEBUG("Window size increased to " << m_window); } void ConsumerPcon::WindowDecrease() { if (!m_useCwa || m_highData > m_recPoint) { const double diff = m_seq - m_highData; BOOST_ASSERT(diff > 0); m_recPoint = m_seq + (m_addRttSuppress * diff); if (m_ccAlgorithm == CcAlgorithm::AIMD) { // Normal TCP Decrease: m_ssthresh = m_window * m_beta; m_window = m_ssthresh; } else if (m_ccAlgorithm == CcAlgorithm::CUBIC) { CubicDecrease(); } else if (m_ccAlgorithm == CcAlgorithm::BIC) { BicDecrease(); } else { BOOST_ASSERT_MSG(false, "Unknown CC Algorithm"); } // Window size cannot be reduced below initial size if (m_window < m_initialWindow) { m_window = m_initialWindow; } NS_LOG_DEBUG("Window size decreased to " << m_window); } else { NS_LOG_DEBUG("Window decrease suppressed, HighData: " << m_highData << ", RecPoint: " << m_recPoint); } } void ConsumerPcon::BicIncrease() { if (m_window < BIC_LOW_WINDOW) { // Normal TCP AIMD behavior if (m_window < m_ssthresh) { m_window = m_window + 1; } else { m_window = m_window + 1.0 / m_window; } } else if (!m_isBicSs) { // Binary increase if (m_bicTargetWin - m_window < BIC_MAX_INCREMENT) { // Binary search m_window += (m_bicTargetWin - m_window) / m_window; } else { m_window += BIC_MAX_INCREMENT / m_window; // Additive increase } // FIX for equal double values. if (m_window + 0.00001 < m_bicMaxWin) { m_bicMinWin = m_window; m_bicTargetWin = (m_bicMaxWin + m_bicMinWin) / 2; } else { m_isBicSs = true; m_bicSsCwnd = 1; m_bicSsTarget = m_window + 1.0; m_bicMaxWin = std::numeric_limits<double>::max(); } } else { // BIC slow start m_window += m_bicSsCwnd / m_window; if (m_window >= m_bicSsTarget) { m_bicSsCwnd = 2 * m_bicSsCwnd; m_bicSsTarget = m_window + m_bicSsCwnd; } if (m_bicSsCwnd >= BIC_MAX_INCREMENT) { m_isBicSs = false; } } } void ConsumerPcon::BicDecrease() { // BIC Decrease if (m_window >= BIC_LOW_WINDOW) { auto prev_max = m_bicMaxWin; m_bicMaxWin = m_window; m_window = m_window * m_cubicBeta; m_bicMinWin = m_window; if (prev_max > m_bicMaxWin) { // Fast Convergence m_bicMaxWin = (m_bicMaxWin + m_bicMinWin) / 2; } m_bicTargetWin = (m_bicMaxWin + m_bicMinWin) / 2; } else { // Normal TCP Decrease: m_ssthresh = m_window * m_cubicBeta; m_window = m_ssthresh; } } void ConsumerPcon::CubicIncrease() { // 1. Time since last congestion event in Seconds const double t = time::duration_cast<time::microseconds>( time::steady_clock::now() - m_cubicLastDecrease).count() / 1e6; // 2. Time it takes to increase the window to cubic_wmax // K = cubic_root(W_max*(1-beta_cubic)/C) (Eq. 2) const double k = std::cbrt(m_cubicWmax * (1 - m_cubicBeta) / CUBIC_C); // 3. Target: W_cubic(t) = C*(t-K)^3 + W_max (Eq. 1) const double w_cubic = CUBIC_C * std::pow(t - k, 3) + m_cubicWmax; // 4. Estimate of Reno Increase (Currently Disabled) // const double rtt = m_rtt->GetCurrentEstimate().GetSeconds(); // const double w_est = m_cubic_wmax*m_beta + (3*(1-m_beta)/(1+m_beta)) * (t/rtt); constexpr double w_est = 0.0; // Actual adaptation if (m_window < m_ssthresh) { m_window += 1.0; } else { BOOST_ASSERT(m_cubicWmax > 0); double cubic_increment = std::max(w_cubic, w_est) - m_window; // Cubic increment must be positive: // Note: This change is not part of the RFC, but I added it to improve performance. if (cubic_increment < 0) { cubic_increment = 0.0; } m_window += cubic_increment / m_window; } } void ConsumerPcon::CubicDecrease() { // This implementation is ported from https://datatracker.ietf.org/doc/rfc8312/ const double FAST_CONV_DIFF = 1.0; // In percent // A flow remembers the last value of W_max, // before it updates W_max for the current congestion event. // Current w_max < last_wmax if (m_useCubicFastConv && m_window < m_cubicLastWmax * (1 - FAST_CONV_DIFF / 100)) { m_cubicLastWmax = m_window; m_cubicWmax = m_window * (1.0 + m_cubicBeta) / 2.0; } else { // Save old cwnd as w_max: m_cubicLastWmax = m_window; m_cubicWmax = m_window; } m_ssthresh = m_window * m_cubicBeta; m_ssthresh = std::max<double>(m_ssthresh, m_initialWindow); m_window = m_ssthresh; m_cubicLastDecrease = time::steady_clock::now(); } } // namespace ndn } // namespace ns3
ndn-congestion-topo-plugin.cpp
#include "ns3/ndnSIM/apps/ndn-consumer-pcon.hpp" #include "ns3/ndnSIM/apps/ndn-consumer-window.hpp" #include "ns3/core-module.h" #include "ns3/network-module.h" #include "ns3/ndnSIM-module.h" #include <iostream> #include <fstream> namespace ns3 { int main(int argc, char* argv[] ) { ns3::ndn::ConsumerPcon consumer ; CommandLine cmd; cmd.Parse(argc, argv); AnnotatedTopologyReader topologyReader("", 25); topologyReader.SetFileName("src/ndnSIM/examples/topologies/topo-6-node.txt"); topologyReader.Read(); // Install NDN stack on all nodes ndn::StackHelper ndnHelper; ndnHelper.setPolicy("nfd::cs::lru"); ndnHelper.setCsSize(0); ndnHelper.InstallAll(); // Choosing forwarding strategy ndn::StrategyChoiceHelper::InstallAll("/prefix", "/localhost/nfd/strategy/best-route"); // Installing global routing interface on all nodes ndn::GlobalRoutingHelper ndnGlobalRoutingHelper; ndnGlobalRoutingHelper.InstallAll(); // Getting containers for the consumer/producer Ptr<Node> consumer1 = Names::Find<Node>("Src1"); Ptr<Node> consumer2 = Names::Find<Node>("Src2"); Ptr<Node> producer1 = Names::Find<Node>("Dst1"); Ptr<Node> producer2 = Names::Find<Node>("Dst2"); ndn::AppHelper consumerHelper("ns3::ndn::ConsumerCbr"); consumerHelper.SetAttribute("Frequency", StringValue("90")); // 100 interests a second // on the first consumer node install a Consumer application // that will express interests in /dst1 namespace consumerHelper.SetPrefix("/dst1"); consumerHelper.Install(consumer1); // on the second consumer node install a Consumer application // that will express interests in /dst2 namespace consumerHelper.SetPrefix("/dst2"); consumerHelper.Install(consumer2); ndn::AppHelper producerHelper("ns3::ndn::Producer"); producerHelper.SetAttribute("PayloadSize", StringValue("1024")); // Register /dst1 prefix with global routing controller and // install producer that will satisfy Interests in /dst1 namespace ndnGlobalRoutingHelper.AddOrigins("/dst1", producer1); producerHelper.SetPrefix("/dst1"); producerHelper.Install(producer1); // Register /dst2 prefix with global routing controller and // install producer that will satisfy Interests in /dst2 namespace ndnGlobalRoutingHelper.AddOrigins("/dst2", producer2); producerHelper.SetPrefix("/dst2"); producerHelper.Install(producer2); // Calculate and install FIBs ndn::GlobalRoutingHelper::CalculateRoutes(); Simulator::Stop(Seconds(40.0)); std::string file = "outputFile.txt"; std::ofstream out; out.open(file, std::fstream::app); // if you want to truncate the file instead of appending to it use "trunc" instead of "app" auto *coutbuf = std::cout.rdbuf(); std::cout.rdbuf(out.rdbuf()); std::cout << " The value of m_highData " << consumer.m_highData << std::endl; std::cout << " The value of m_window " << consumer.m_window << std::endl; /* reset cout buffer **/ std::cout.rdbuf(coutbuf); Simulator::Run(); Simulator::Destroy(); return 0; } } // namespace ns3 int main(int argc, char* argv[]) { return ns3::main(argc, argv); }
Merci
A voir également:
- Affichage dans ndnSIM
- Affichage double ecran - Guide
- Windows 11 affichage classique - Guide
- Problème affichage fenêtre windows 10 - Guide
- Problème affichage page internet google chrome - Forum Téléphones & tablettes Android
- Pinterest problème affichage ✓ - Forum Réseaux sociaux
Bonjour mamiemando ,
c'est à propos la transmission IP-V6 et pas NDN
Merci
L'important ce n'est pas l'exemple, c'est le concept présenté dans le tutoriel (notamment celui de probe). Certes, la documentation illustre cette notion avec une simulation mettant en jeu IPv6, mais le principe reste le même dans NDN. La partie importante, c'est celle avec les lignes de code ajoutée en vert (celle qui commencent par un +) qu'il faut compléter et adapter à ton cas d'usage.