wella_salwa
Messages postés41Date d'inscriptionlundi 31 octobre 2022StatutMembreDernière intervention15 janvier 2025
-
Modifié le 11 avril 2023 à 16:49
mamiemando
Messages postés33549Date d'inscriptionjeudi 12 mai 2005StatutModérateurDernière intervention 4 mars 2025
-
12 avril 2023 à 13:32
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>usingnamespace std;NS_LOG_COMPONENT_DEFINE("ndn.ConsumerPcon");namespace ns3 {namespace ndn {NS_OBJECT_ENSURE_REGISTERED(ConsumerPcon);
constexpr double ConsumerPcon::CUBIC_C;constexpruint32_tConsumerPcon::BIC_MAX_INCREMENT;constexpruint32_tConsumerPcon::BIC_LOW_WINDOW;ConsumerPconconsumer ;
TypeId
ConsumerPcon::GetTypeId(){staticTypeIdtid =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 testingMakeDoubleAccessor(&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_tsequenceNum = data->getName().get(-1).toSequenceNumber();// Set highest received Data to sequence numberif(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_tsequenceNum){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);}}elseif(m_ccAlgorithm == CcAlgorithm::CUBIC){CubicIncrease();}elseif(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){constdouble 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;}elseif(m_ccAlgorithm == CcAlgorithm::CUBIC){CubicDecrease();}elseif(m_ccAlgorithm == CcAlgorithm::BIC){BicDecrease();}else{BOOST_ASSERT_MSG(false,"Unknown CC Algorithm");}// Window size cannot be reduced below initial sizeif(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 behaviorif(m_window < m_ssthresh){
m_window = m_window +1;}else{
m_window = m_window +1.0/ m_window;}}elseif(!m_isBicSs){// Binary increaseif(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 Decreaseif(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 Secondsconstdouble 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)constdouble k = std::cbrt(m_cubicWmax *(1- m_cubicBeta)/ CUBIC_C);// 3. Target: W_cubic(t) = C*(t-K)^3 + W_max (Eq. 1)constdouble 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 adaptationif(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/constdouble 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_wmaxif(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 {intmain(int argc,char* argv[]){
ns3::ndn::ConsumerPconconsumer ;CommandLinecmd;
cmd.Parse(argc, argv);AnnotatedTopologyReadertopologyReader("",25);
topologyReader.SetFileName("src/ndnSIM/examples/topologies/topo-6-node.txt");
topologyReader.Read();// Install NDN stack on all nodes
ndn::StackHelperndnHelper;
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::GlobalRoutingHelperndnGlobalRoutingHelper;
ndnGlobalRoutingHelper.InstallAll();// Getting containers for the consumer/producerPtr<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::AppHelperconsumerHelper("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::AppHelperproducerHelper("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::stringfile ="outputFile.txt";
std::ofstreamout;
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();return0;}}// namespace ns3intmain(int argc,char* argv[]){return ns3::main(argc, argv);}
wella_salwa
Messages postés41Date d'inscriptionlundi 31 octobre 2022StatutMembreDernière intervention15 janvier 2025 12 avril 2023 à 12:02
Bonjour mamiemando ,
c'est à propos la transmission IP-V6 et pas NDN
Merci
mamiemando
Messages postés33549Date d'inscriptionjeudi 12 mai 2005StatutModérateurDernière intervention 4 mars 20257 829
>
wella_salwa
Messages postés41Date d'inscriptionlundi 31 octobre 2022StatutMembreDernière intervention15 janvier 2025 12 avril 2023 à 13:32
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.
std::stringprobeType;
std::stringtracePath;if(useV6 ==false){...
probeType ="ns3::Ipv4PacketProbe";
tracePath ="/NodeList/*/$ns3::Ipv4L3Protocol/Tx";}else{...
probeType ="ns3::Ipv6PacketProbe";
tracePath ="/NodeList/*/$ns3::Ipv6L3Protocol/Tx";}...// Use GnuplotHelper to plot the packet byte count over timeGnuplotHelperplotHelper;// Configure the plot. The first argument is the file name prefix// for the output files generated. The second, third, and fourth// arguments are, respectively, the plot title, x-axis, and y-axis labels
plotHelper.ConfigurePlot("seventh-packet-byte-count","Packet Byte Count vs. Time","Time(Seconds)","Packet Byte Count");// Specify the probe type, trace source path (in configuration namespace), and// probe output trace source ("OutputBytes") to plot. The fourth argument// specifies the name of the data series label on the plot. The last// argument formats the plot by specifying where the key should be placed.
plotHelper.PlotProbe(probeType,
tracePath,"OutputBytes","Packet Byte Count",
GnuplotAggregator::KEY_BELOW);// Use FileHelper to write out the packet byte count over timeFileHelperfileHelper;// Configure the file to be written, and the formatting of output data.
fileHelper.ConfigureFile("seventh-packet-byte-count",
FileAggregator::FORMATTED);// Set the labels for this formatted output file.
fileHelper.Set2dFormat("Time (Seconds) = %.3e\tPacket Byte Count = %.0f");// Specify the probe type, probe path (in configuration namespace), and// probe output trace source ("OutputBytes") to write.
fileHelper.WriteProbe(probeType,
tracePath,"OutputBytes");
12 avril 2023 à 12:02
Bonjour mamiemando ,
c'est à propos la transmission IP-V6 et pas NDN
Merci
12 avril 2023 à 13:32
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.