From 8dfa4ffef44a292856b4c2e063267c73cb391cb0 Mon Sep 17 00:00:00 2001 From: Lv Date: Fri, 1 Jul 2022 06:12:20 -0700 Subject: [PATCH] fast-mircc --- ns-3/src/ndnSIM/apps/mircc-consumer.cpp | 44 ++------ ns-3/src/ndnSIM/apps/mircc-consumer.hpp | 6 +- scenario/extensions/mircc-strategy.cpp | 129 ++++++++++++++++++++++-- scenario/extensions/mircc-strategy.hpp | 62 +++++++++++- scenario/scenarios/dsccp3-1.cpp | 14 +-- 5 files changed, 205 insertions(+), 50 deletions(-) diff --git a/ns-3/src/ndnSIM/apps/mircc-consumer.cpp b/ns-3/src/ndnSIM/apps/mircc-consumer.cpp index e090d76..18c6c4e 100644 --- a/ns-3/src/ndnSIM/apps/mircc-consumer.cpp +++ b/ns-3/src/ndnSIM/apps/mircc-consumer.cpp @@ -11,6 +11,7 @@ #include "ns3/double.h" #include +#include NS_LOG_COMPONENT_DEFINE("ndn.ConsumerMIRCC"); @@ -67,23 +68,6 @@ ConsumerMIRCC::~ConsumerMIRCC() } -void -ConsumerMIRCC::ScheduleNextPacket() -{ - std::printf(""); - // double mean = 8.0 * m_payloadSize / m_desiredRate.GetBitRate (); - // std::cout << "next: " << Simulator::Now().ToDouble(Time::S) + mean << "s\n"; -/* - if (m_firstTime) { - m_sendEvent = Simulator::Schedule(Seconds(0.0), &Consumer::, this); - m_firstTime = false; - } - else if (!m_sendEvent.IsRunning()) - m_sendEvent = Simulator::Schedule((m_random == 0) ? Seconds(1.0 / m_frequency) - : Seconds(m_random->GetValue()), - &Consumer::SendPacket, this);*/ -} - void ConsumerMIRCC:: StopApplication() { @@ -247,8 +231,6 @@ ConsumerMIRCC::SendPacket(uint64_t pathId,uint64_t classId) seq = m_seq++; } // - seq2ClassId[seq] = classId; - seq2PathId[seq] = pathId; if (classId == 1) @@ -296,8 +278,6 @@ ConsumerMIRCC::SendPacket(uint64_t pathId,uint64_t classId) m_transmittedInterests(interest, this, m_face); m_appLink->onReceiveInterest(*interest); - //这个函数只负责发包,不在负责调用下一个包的发送 - //ScheduleNextPacket(); } uint64_t @@ -386,7 +366,6 @@ ConsumerMIRCC:: PathExplorate() } explore_event = Simulator::Schedule(Seconds(0.1), &ConsumerMIRCC::PathExplorate, this); - //PathId为0表示正在进行路径探索 SendPacket(0,1); @@ -489,18 +468,9 @@ ConsumerMIRCC::OnData(shared_ptr data) { tryBindRandId(seq, *tmpPathid); } - //if (appid == 1) - //NS_LOG_DEBUG("seq " << seq << " ClassId " << seq2ClassId[seq]); - if (seq2ClassId[seq] == 1) - { - pktcnt_p += 1; - }else - { - pktcnt_s += 1; - } - seq2ClassId.erase(seq); + + seq2RandomId.erase(seq); - seq2PathId.erase(seq); @@ -566,7 +536,13 @@ ConsumerMIRCC::OnTimeout(uint32_t sequenceNumber) { m_rtt->SentSeq(SequenceNumber32(sequenceNumber), 1); // make sure to disable RTT calculation for this sample m_retxSeqs.insert(sequenceNumber); - SchedulePacketForPathId(seq2PathId[sequenceNumber], seq2ClassId[sequenceNumber]); +} + +void +ConsumerMIRCC::ScheduleNextPacket() +{ + uint64_t a = 1; + } }// namespace ndn } // namespace ns3 diff --git a/ns-3/src/ndnSIM/apps/mircc-consumer.hpp b/ns-3/src/ndnSIM/apps/mircc-consumer.hpp index 5ee5123..75daac9 100644 --- a/ns-3/src/ndnSIM/apps/mircc-consumer.hpp +++ b/ns-3/src/ndnSIM/apps/mircc-consumer.hpp @@ -34,8 +34,7 @@ protected: * \brief Constructs the Interest packet and sends it using a callback to the underlying NDN * protocol */ - virtual void - ScheduleNextPacket(); + void @@ -63,6 +62,9 @@ protected: Ptr m_random; std::string m_randomType; + virtual void + ScheduleNextPacket(); + private: //路径id到发送事件id的一一映射关系 std:: unordered_map pathId2EventId_p,pathId2EventId_s; diff --git a/scenario/extensions/mircc-strategy.cpp b/scenario/extensions/mircc-strategy.cpp index f010308..6f508dd 100644 --- a/scenario/extensions/mircc-strategy.cpp +++ b/scenario/extensions/mircc-strategy.cpp @@ -44,7 +44,8 @@ namespace nfd { m_d[inface(tmp.getId())] = 0.03; - sendQueueInterest(tmp.getId()); + m_running[inface(tmp.getId())] = 0; + //sendQueueInterest(tmp.getId()); calcRt(tmp.getId()); @@ -56,8 +57,16 @@ namespace nfd { { //设置下一次发送,根据兴趣包与数据包的大小之比,计算出兴趣包可用带宽,进而计算出每发送一个兴趣包需要的时间,最小为1ms - time::nanoseconds ttime(std::max((uint64_t)1,(uint64_t)1000000000 * DATA_SIZE / m_linkC[inface(mface)])); - getScheduler().schedule(ttime, bind(&MIRCCStrategy::sendQueueInterest, this, mface)); + if (m_Queue[inface(mface)].qp.size() + m_Queue[inface(mface)].qs.size() > 1) + {// + time::nanoseconds ttime(std::max((uint64_t)1,(uint64_t)1000000000 * DATA_SIZE / m_linkC[inface(mface)])); + getScheduler().schedule(ttime, bind(&MIRCCStrategy::sendQueueInterest, this, mface)); + }else + { + m_running[inface(mface)] = 0; + } + //std::cout << (uint64_t)1000000000 * DATA_SIZE / m_linkC[inface(mface)] << std::endl; + //分三种情况讨论,只有第一类兴趣包可以发,只有第二类兴趣包可以发,两类可以发(选择最早到达的) if (m_Queue[inface(mface)].qp.size() > 0 and m_Queue[inface(mface)].qs.size() == 0) @@ -67,7 +76,7 @@ namespace nfd { m_Queue[inface(mface)].qp.pop_front(); m_Queue[inface(mface)].tp.pop_front(); m_Queue[inface(mface)].pp.pop_front(); - + m_on++; }else if (m_Queue[inface(mface)].qs.size() > 0 and m_Queue[inface(mface)].qp.size() == 0) { shared_ptr interest = m_Queue[inface(mface)].qs.front(); @@ -75,8 +84,10 @@ namespace nfd { m_Queue[inface(mface)].qs.pop_front(); m_Queue[inface(mface)].ts.pop_front(); m_Queue[inface(mface)].ps.pop_front(); + m_on++; }else if (m_Queue[inface(mface)].qs.size() > 0 and m_Queue[inface(mface)].qp.size() > 0) { + m_on++; if (m_Queue[inface(mface)].tp.front() < m_Queue[inface(mface)].ts.front()) { shared_ptr interest =m_Queue[inface(mface)].qp.front(); @@ -94,8 +105,45 @@ namespace nfd { } }else { + m_miss++; } + /* + //设置下一次发送,根据兴趣包与数据包的大小之比,计算出兴趣包可用带宽,进而计算出每发送一个兴趣包需要的时间,最小为1ms + time::nanoseconds ttime(std::max((uint64_t)1,(uint64_t)1000000000 * DATA_SIZE / m_linkC[inface(mface)])); + getScheduler().schedule(ttime, bind(&MIRCCStrategy::sendQueueInterest, this, mface)); + + shared_ptr fi,si; + time::steady_clock::TimePoint ft,st; + shared_ptr fp,sp; + m_Queue[inface(mface)].f.getHead(fi,ft,fp); + m_Queue[inface(mface)].s.getHead(si,st,sp); + + + //分三种情况讨论,只有第一类兴趣包可以发,只有第二类兴趣包可以发,两类可以发(选择最早到达的) + if (m_Queue[inface(mface)].f.getSize() > 0 and m_Queue[inface(mface)].s.getSize() == 0) + { + sendInterest(fp,FaceEndpoint(*getFaceTable().get(mface),0),*fi); + m_Queue[inface(mface)].f.deQueueFront(); + + }else if (m_Queue[inface(mface)].s.getSize() > 0 and m_Queue[inface(mface)].f.getSize() == 0) + { + sendInterest(sp,FaceEndpoint(*getFaceTable().get(mface),0),*si); + m_Queue[inface(mface)].s.deQueueFront(); + }else if (m_Queue[inface(mface)].f.getSize() > 0 and m_Queue[inface(mface)].s.getSize() > 0) + { + if (ft < st) + { + sendInterest(fp,FaceEndpoint(*getFaceTable().get(mface),0),*fi); + m_Queue[inface(mface)].f.deQueueFront(); + }else + { + sendInterest(sp,FaceEndpoint(*getFaceTable().get(mface),0),*si); + m_Queue[inface(mface)].s.deQueueFront(); + } + }else + { + }*/ } @@ -105,12 +153,12 @@ namespace nfd { //每100ms自动重新计算Rt time::nanoseconds ttime(100000000); getScheduler().schedule(ttime, std::bind(&MIRCCStrategy::calcRt, this, mface)); - + // std::cout << (double)m_miss / std::max(m_on,(uint64_t)1) << std::endl; long long ia,ib,Rp,Rs; double db; Rp = m_Rp_base[inface(mface)] + m_Rp_ex[inface(mface)]; Rs = m_Rs_base[inface(mface)] + m_Rs_ex[inface(mface)]; - + // NS_LOG_DEBUG("face:" << mface << "d:" << m_d[inface(mface)]); // NS_LOG_DEBUG("Rp: " << Rp << " Rs: " << Rs << " Yt: " << m_Yp[inface(mface)] << " C:" << m_linkC[inface(mface)]); @@ -210,11 +258,13 @@ namespace nfd { //返回兴趣包个数*兴趣包大小*数据包与兴趣包大小之比 uint64_t time = 10;//保持Rt计算周期一致 return (m_Queue[inface(mface)].qp.size() + m_Queue[inface(mface)].qs.size()) * DATA_SIZE * time; + //return (m_Queue[inface(mface)].f.getSize() + m_Queue[inface(mface)].s.getSize()) * DATA_SIZE * time; } void MIRCCStrategy::pushQueueInterest(FaceId mface,const shared_ptr& interest,const shared_ptr& pitEntry) { + //// NS_LOG_DEBUG("MIRCC pushQueueInterest"); uint64_t p = *(interest->getTag()); //如果是第一类兴趣包 @@ -233,6 +283,13 @@ namespace nfd { m_Queue[inface(mface)].qp.push_back(interest); m_Queue[inface(mface)].tp.push_back(time::steady_clock::now()); m_Queue[inface(mface)].pp.push_back(pitEntry); + + if (m_running[inface(mface)] == 0) + { + m_running[inface(mface)] = 1; + time::nanoseconds ttime(std::max((uint64_t)1,(uint64_t)1000000000 * DATA_SIZE / m_linkC[inface(mface)])); + getScheduler().schedule(ttime, bind(&MIRCCStrategy::sendQueueInterest, this, mface)); + } }else { //否则当前兴趣包丢失 @@ -246,6 +303,13 @@ namespace nfd { m_Queue[inface(mface)].qp.push_back(interest); m_Queue[inface(mface)].tp.push_back(time::steady_clock::now()); m_Queue[inface(mface)].pp.push_back(pitEntry); + + if (m_running[inface(mface)] == 0) + { + m_running[inface(mface)] = 1; + time::nanoseconds ttime(std::max((uint64_t)1,(uint64_t)1000000000 * DATA_SIZE / m_linkC[inface(mface)])); + getScheduler().schedule(ttime, bind(&MIRCCStrategy::sendQueueInterest, this, mface)); + } } }else { @@ -261,9 +325,62 @@ namespace nfd { m_Queue[inface(mface)].qs.push_back(interest); m_Queue[inface(mface)].ts.push_back(time::steady_clock::now()); m_Queue[inface(mface)].ps.push_back(pitEntry); + + if (m_running[inface(mface)] == 0) + { + m_running[inface(mface)] = 1; + time::nanoseconds ttime(std::max((uint64_t)1,(uint64_t)1000000000 * DATA_SIZE / m_linkC[inface(mface)])); + getScheduler().schedule(ttime, bind(&MIRCCStrategy::sendQueueInterest, this, mface)); + } } } + + /* + uint64_t p = *(interest->getTag()); + //如果是第一类兴趣包 + if (p == 1) + { + //如果队列已经满了 + if (m_Queue[inface(mface)].f.getSize() + m_Queue[inface(mface)].s.getSize() >= 10) + { + //如果存在第二类兴趣包可以删除 + if (m_Queue[inface(mface)].s.getSize() > 0) + { + //删掉第二类兴趣包最后一个,把当前第一类兴趣包加入 + + m_Queue[inface(mface)].s.deQueueBack(); + m_Queue[inface(mface)].f.enQueue(interest,time::steady_clock::now(),pitEntry); + }else + { + //否则当前兴趣包丢失 + + //这里应该回传Nack,还没有写完 + this->rejectPendingInterest(pitEntry); + } + }else + { + //直接将当前兴趣包加入第一类兴趣包队列末尾 + m_Queue[inface(mface)].f.enQueue(interest,time::steady_clock::now(),pitEntry); + + } + }else + { + //如果队列已经满了 + if (m_Queue[inface(mface)].f.getSize() + m_Queue[inface(mface)].s.getSize() >= 10) + { + //当前兴趣包丢失 + this->rejectPendingInterest(pitEntry); + //这里是否应该回传Nack不确定,需要回去看论文,第二类兴趣包处理方式似乎与第一类不同,还没有写完 + }else + { + //将但钱兴趣包加入第二类末尾 + + + m_Queue[inface(mface)].s.enQueue(interest,time::steady_clock::now(),pitEntry); + } + + }*/ } void diff --git a/scenario/extensions/mircc-strategy.hpp b/scenario/extensions/mircc-strategy.hpp index 9173402..d7eff56 100644 --- a/scenario/extensions/mircc-strategy.hpp +++ b/scenario/extensions/mircc-strategy.hpp @@ -23,7 +23,62 @@ namespace nfd { std:: deque> pp,ps; }; + + class cirQueue + { + public: + bool enQueue(shared_ptr interest,time::steady_clock::TimePoint tim,shared_ptr entry) + { + if ((rear + 1) % 10 == front) + return false; + i[rear] = interest; + t[rear] = tim; + p[rear] = entry; + rear = (rear + 1) % 10; + siz += 1; + return true; + } + bool deQueueFront() + { + if (front == rear) + return false; + front = (front + 1) % 10; + siz -= 1; + return true; + } + bool deQueueBack() + { + if (front == rear) + return false; + rear = (rear + 10 - 1) % 10; + siz -= 1; + return true; + } + bool getHead(shared_ptr &interest,time::steady_clock::TimePoint &tim,shared_ptr &entry) + { + if (front == rear) + return false; + interest = i[front]; + tim = t[front]; + entry = p[front]; + return true; + } + uint64_t getSize() + { + return siz; + } + private: + shared_ptr i[20]; + time::steady_clock::TimePoint t[20]; + shared_ptr p[20]; + uint64_t rear = 0,front = 0,siz = 0; + }; + class MIRCCQueueF + { + public: + cirQueue f,s; + }; /* MIRCC 策略实现 */ @@ -63,6 +118,7 @@ namespace nfd { const double m_rtt_a = 0.7;//RTT更新系数 + uint64_t m_miss = 0,m_on = 0; uint64_t m_Rp_base[MAX_FACE];//Rp的base速率 uint64_t m_Rp_ex[MAX_FACE];//Rp的ex速率 uint64_t m_Rs_base[MAX_FACE];//Rs的base速率 @@ -72,12 +128,16 @@ namespace nfd { uint64_t m_Ys[MAX_FACE];//本周起的Ys(t) uint64_t m_Ys_old[MAX_FACE];//上一个周期的Ys(t) uint64_t m_linkC[MAX_FACE];//每一个链路的带宽,单位为比特 + uint64_t m_running[MAX_FACE]; double m_d[MAX_FACE];//维护每一个face的RTT 秒 //注意,此处没有维护数据包/兴趣包,算法中采用固定的数据包大小 + MIRCCQueue m_Queue[MAX_FACE];//用于出口排队转发兴趣 - + //MIRCCQueueF m_Queue[MAX_FACE];//用于出口排队转发兴趣 + + //发送mface端口1个正在排队的兴趣包,并设置下一次发送时间 void sendQueueInterest(FaceId mface); diff --git a/scenario/scenarios/dsccp3-1.cpp b/scenario/scenarios/dsccp3-1.cpp index 390c277..2a33ac0 100644 --- a/scenario/scenarios/dsccp3-1.cpp +++ b/scenario/scenarios/dsccp3-1.cpp @@ -43,7 +43,7 @@ namespace ns3 ndn::AppHelper consumerHelper("ns3::ndn::ConsumerMIRCC"); consumerHelper.SetAttribute("logtms",StringValue("0")); consumerHelper.SetAttribute("start_ms",StringValue("0")); - consumerHelper.SetAttribute("end_ms",StringValue("200000")); + consumerHelper.SetAttribute("end_ms",StringValue("8000")); // C1 consumerHelper.SetPrefix("/A"); @@ -51,15 +51,15 @@ namespace ns3 // C2 consumerHelper.SetPrefix("/B"); - consumerHelper.SetAttribute("start_ms",StringValue("30000")); - consumerHelper.SetAttribute("end_ms",StringValue("200000")); + consumerHelper.SetAttribute("start_ms",StringValue("2000")); + consumerHelper.SetAttribute("end_ms",StringValue("8000")); consumerHelper.Install("C2"); // C3 consumerHelper.SetPrefix("/C"); - consumerHelper.SetAttribute("start_ms",StringValue("60000")); - consumerHelper.SetAttribute("end_ms",StringValue("200000")); - consumerHelper.SetAttribute("greedy_ms",StringValue("150000")); + consumerHelper.SetAttribute("start_ms",StringValue("4000")); + consumerHelper.SetAttribute("end_ms",StringValue("8000")); + consumerHelper.SetAttribute("greedy_ms",StringValue("6000")); consumerHelper.SetAttribute("greedy_rate",StringValue("6000000")); consumerHelper.Install("C3"); @@ -112,7 +112,7 @@ namespace ns3 ndn::FibHelper::AddRoute("R4", "/B", "R5", 0); ndn::FibHelper::AddRoute("R4", "/C", "R5", 0); - Simulator::Stop(Seconds(200.0)); + Simulator::Stop(Seconds(8.0)); ndn::L3RateTracer::InstallAll("dsccp3-1_throughput.txt", Seconds(0.1)); ndn::AppDelayTracer::InstallAll("dsccp3-1_delay.txt");