Compare commits
4 Commits
f12eb9e624
...
307a26ffa4
Author | SHA1 | Date |
---|---|---|
cyp0633 | 307a26ffa4 | |
cyp0633 | 6440cd3d29 | |
cyp0633 | 2138a091e7 | |
cyp0633 | deb041ccc4 |
|
@ -83,9 +83,9 @@ IntHeader::Serialize(Buffer::Iterator start) const
|
|||
}
|
||||
break;
|
||||
case SWIFT:
|
||||
i.WriteU32(swift.nhop);
|
||||
i.WriteU32(swift.ts);
|
||||
i.WriteU32(swift.remote_delay);
|
||||
i.WriteU64(swift.remote_delay);
|
||||
i.WriteU64(swift.ts);
|
||||
i.WriteU64(swift.nhop);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -120,9 +120,9 @@ IntHeader::Deserialize(Buffer::Iterator start)
|
|||
}
|
||||
break;
|
||||
case SWIFT:
|
||||
swift.nhop = i.ReadU32();
|
||||
swift.ts = i.ReadU32();
|
||||
swift.remote_delay = i.ReadU32();
|
||||
swift.remote_delay = i.ReadU64();
|
||||
swift.ts = i.ReadU64();
|
||||
swift.nhop = i.ReadU64();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -155,12 +155,12 @@ class IntHeader
|
|||
struct
|
||||
{
|
||||
// remote queueing delay
|
||||
uint32_t remote_delay;
|
||||
uint64_t remote_delay;
|
||||
// sent timestamp
|
||||
uint32_t ts;
|
||||
uint64_t ts;
|
||||
// hop count
|
||||
// required no internal padding, so outside padding?
|
||||
uint32_t nhop;
|
||||
uint64_t nhop;
|
||||
} swift; // WARNING: Swift fields are serialized and de- in REVERSE ORDER.
|
||||
};
|
||||
|
||||
|
|
|
@ -80,15 +80,21 @@ qbbHeader::SetIntHeader(const IntHeader& _ih)
|
|||
ih = _ih;
|
||||
}
|
||||
|
||||
// Set swift endpoint delay duration, pass sending timestamp
|
||||
void
|
||||
qbbHeader::SetSwiftEndDelay(const uint32_t t4)
|
||||
qbbHeader::SetSwiftEndDelay(const uint64_t t4)
|
||||
{
|
||||
auto swift = &(this->ih.swift);
|
||||
auto t2 = swift->remote_delay;
|
||||
swift->remote_delay = t4 - t2;
|
||||
}
|
||||
|
||||
void
|
||||
qbbHeader::SetSwiftSentTime(const uint64_t t1)
|
||||
{
|
||||
auto swift = &(this->ih.swift);
|
||||
swift->ts = t1;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
qbbHeader::GetPG() const
|
||||
{
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "ns3/header.h"
|
||||
#include "ns3/int-header.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace ns3
|
||||
|
@ -44,7 +45,10 @@ class qbbHeader : public Header
|
|||
void SetTs(uint64_t ts);
|
||||
void SetCnp();
|
||||
void SetIntHeader(const IntHeader& _ih);
|
||||
void SetSwiftEndDelay(uint32_t t4);
|
||||
// Set swift endpoint delay duration, pass sending timestamp
|
||||
void SetSwiftEndDelay(uint64_t t4);
|
||||
// Set swift sending time t_sent (t1)
|
||||
void SetSwiftSentTime(uint64_t t1);
|
||||
|
||||
// Getters
|
||||
/**
|
||||
|
|
|
@ -124,6 +124,9 @@ RdmaEgressQueue::DequeueQindex(int qIndex)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Calculate endpoint delay for Swift CC; actually seems useless, endpoint delay always 0
|
||||
//
|
||||
// In theory it can also use CustomHeader, but since it works, we don't change it
|
||||
void
|
||||
SwiftCalcEndpointDelay(Ptr<Packet> p)
|
||||
{
|
||||
|
@ -135,7 +138,7 @@ SwiftCalcEndpointDelay(Ptr<Packet> p)
|
|||
{ // sending an ACK
|
||||
qbbHeader qh;
|
||||
p->RemoveHeader(qh);
|
||||
auto t4 = (uint32_t)Simulator::Now().GetTimeStep();
|
||||
auto t4 = Simulator::Now().GetNanoSeconds();
|
||||
qh.SetSwiftEndDelay(t4);
|
||||
p->AddHeader(qh);
|
||||
}
|
||||
|
@ -143,15 +146,34 @@ SwiftCalcEndpointDelay(Ptr<Packet> p)
|
|||
p->AddHeader(ph);
|
||||
}
|
||||
|
||||
// Attach t_sent (t1) to header for Swift CC
|
||||
void
|
||||
SwiftAttachTSent(Ptr<Packet> p)
|
||||
{
|
||||
CustomHeader ch(CustomHeader::L2_Header | CustomHeader::L3_Header | CustomHeader::L4_Header);
|
||||
ch.getInt = 1;
|
||||
p->RemoveHeader(ch);
|
||||
if (ch.l3Prot == 0x11)
|
||||
{ // UDP
|
||||
auto t1 = Simulator::Now().GetNanoSeconds();
|
||||
ch.udp.ih.swift.ts = t1;
|
||||
}
|
||||
p->AddHeader(ch);
|
||||
}
|
||||
|
||||
// Determines the next queue index from which to dequeue a packet for transmission, based on
|
||||
// priority and whether the queue is paused due to PFC.
|
||||
//
|
||||
// paused: whether queue i is paused by PFC and shouldn't send packet
|
||||
//
|
||||
// return: -1 for top priority (e.g. ACKs), -1024 for nothing, >0 for corresponding queue index
|
||||
int
|
||||
RdmaEgressQueue::GetNextQindex(bool paused[])
|
||||
{
|
||||
bool found = false;
|
||||
uint32_t qIndex;
|
||||
if (!paused[ack_q_idx] && m_ackQ->GetNPackets() > 0)
|
||||
{
|
||||
{ // top priority queue, try to send first
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -165,22 +187,23 @@ RdmaEgressQueue::GetNextQindex(bool paused[])
|
|||
{
|
||||
uint32_t fcount = m_qpGrp->GetN();
|
||||
uint32_t min_finish_id = 0xffffffff;
|
||||
for (qIndex = 1; qIndex <= fcount; qIndex++)
|
||||
for (qIndex = 1; qIndex <= fcount; qIndex++) // go through all queues
|
||||
{
|
||||
uint32_t idx = (qIndex + m_rrlast) % fcount;
|
||||
uint32_t idx = (qIndex + m_rrlast) % fcount; // start from where we left last time
|
||||
Ptr<RdmaQueuePair> qp = m_qpGrp->Get(idx);
|
||||
if (!paused[qp->m_pg] && qp->GetBytesLeft() > 0 && !qp->IsWinBound())
|
||||
{
|
||||
{ // not paused, not empty, not win bound
|
||||
if (m_qpGrp->Get(idx)->m_nextAvail.GetTimeStep() >
|
||||
Simulator::Now().GetTimeStep())
|
||||
{ // not available now
|
||||
{ // still sending or pacing, not available
|
||||
continue;
|
||||
}
|
||||
res = idx;
|
||||
res = idx; // send from this queue
|
||||
qp->UpdatePacing(); // add another pacing delay to nextAvail
|
||||
break;
|
||||
}
|
||||
else if (qp->IsFinished())
|
||||
{
|
||||
{ // finished
|
||||
min_finish_id = idx < min_finish_id ? idx : min_finish_id;
|
||||
}
|
||||
}
|
||||
|
@ -437,10 +460,10 @@ QbbNetDevice::DequeueAndTransmit(void)
|
|||
{
|
||||
int qIndex = m_rdmaEQ->GetNextQindex(m_paused);
|
||||
// std::cout << "qIndex " << qIndex << std::endl;
|
||||
if (qIndex != -1024)
|
||||
if (qIndex != -1024) // there's something to transmit
|
||||
{
|
||||
if (qIndex == -1)
|
||||
{ // high prio
|
||||
{ // high prio, e.g. ACK
|
||||
p = m_rdmaEQ->DequeueQindex(qIndex);
|
||||
if (IntHeader::mode == IntHeader::SWIFT)
|
||||
{ // those ACKs will be put in high priority queue
|
||||
|
@ -470,12 +493,12 @@ QbbNetDevice::DequeueAndTransmit(void)
|
|||
totalBytesSent += p->GetSize();
|
||||
return;
|
||||
}
|
||||
// a qp dequeue a packet
|
||||
// a qp dequeue a packet, normal priority
|
||||
Ptr<RdmaQueuePair> lastQp = m_rdmaEQ->GetQp(qIndex);
|
||||
p = m_rdmaEQ->DequeueQindex(qIndex);
|
||||
// if (p==NULL)
|
||||
// std::cout << "p is null" << std::endl;
|
||||
|
||||
SwiftAttachTSent(p);
|
||||
// transmit
|
||||
m_traceQpDequeue(p, lastQp);
|
||||
TransmitStart(p);
|
||||
|
|
|
@ -2025,9 +2025,9 @@ void
|
|||
RdmaHw::HandleAckSwift(Ptr<RdmaQueuePair> qp, Ptr<Packet> p, CustomHeader& ch)
|
||||
{
|
||||
auto ih = ch.ack.ih.swift;
|
||||
std::cout << "Hops: " << ih.nhop << ", Remote Delay: " << ih.remote_delay << std::endl;
|
||||
std::cout << "[SWIFT] Hops: " << ih.nhop << ", Remote Delay: " << ih.remote_delay << std::endl;
|
||||
uint32_t ack_seq = ch.ack.seq;
|
||||
auto rtt = (uint32_t)Simulator::Now().GetNanoSeconds() - ih.ts;
|
||||
auto rtt = Simulator::Now().GetNanoSeconds() - ih.ts;
|
||||
auto fabric_delay = rtt - ih.remote_delay;
|
||||
|
||||
// on receiving ack
|
||||
|
@ -2040,18 +2040,20 @@ RdmaHw::HandleAckSwift(Ptr<RdmaQueuePair> qp, Ptr<Packet> p, CustomHeader& ch)
|
|||
std::min(swift_min_cwnd, std::max(swift_max_cwnd, std::min(fab_cwnd, endpoint_cwnd)));
|
||||
if (cwnd < qp->swift.m_cwnd_prev)
|
||||
{
|
||||
qp->swift.m_t_last_decrease = Simulator::Now().GetTimeStep();
|
||||
qp->swift.m_t_last_decrease = Simulator::Now();
|
||||
}
|
||||
if (cwnd < 1)
|
||||
{
|
||||
qp->swift.m_pacing_delay = rtt * 1.0 / cwnd;
|
||||
qp->SetWin(INT_MAX); // to make sure sending is only pacing-bound, but not window-bound
|
||||
qp->UpdatePacing();
|
||||
}
|
||||
else
|
||||
{
|
||||
qp->swift.m_pacing_delay = 0;
|
||||
qp->SetWin((uint32_t)cwnd);
|
||||
}
|
||||
std::cout << "[SWIFT] cwnd: " << cwnd << ", rate: " << qp->m_rate << std::endl;
|
||||
}
|
||||
|
||||
// calculate target fabric delay
|
||||
|
@ -2076,7 +2078,7 @@ RdmaHw::GetCwndSwift(Ptr<RdmaQueuePair> qp,
|
|||
uint64_t target_delay,
|
||||
uint64_t curr_delay) const
|
||||
{
|
||||
bool canDecrease = ch.ack.ih.swift.remote_delay > qp->swift.m_t_last_decrease;
|
||||
bool canDecrease = ch.ack.ih.swift.remote_delay > qp->swift.m_t_last_decrease.GetNanoSeconds();
|
||||
double cwnd = qp->swift.m_cwnd_prev;
|
||||
if (curr_delay < target_delay)
|
||||
{
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include <ns3/udp-header.h>
|
||||
#include <ns3/uinteger.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
|
||||
|
@ -79,10 +81,12 @@ RdmaQueuePair::RdmaQueuePair(uint16_t pg,
|
|||
|
||||
swift.m_lastUpdateSeq = 0;
|
||||
swift.m_lastEndpointDelay = 0;
|
||||
swift.m_t_last_decrease = 0;
|
||||
swift.m_t_last_decrease = Time(0);
|
||||
swift.m_curRate = 0;
|
||||
swift.m_retransmit_cnt = 0;
|
||||
swift.m_cwnd_prev = 0;
|
||||
swift.m_cwnd_prev = 0.0;
|
||||
swift.m_pacing_delay = 0;
|
||||
swift.num_acked = 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -163,6 +167,17 @@ RdmaQueuePair::IsWinBound() const
|
|||
return w != 0 && GetOnTheFly() >= w;
|
||||
}
|
||||
|
||||
void
|
||||
RdmaQueuePair::UpdatePacing()
|
||||
{
|
||||
// Update next avail time, just add a pacing delay
|
||||
// Minimum pacing delay is 1 RTT, and the sending process should be shorter?
|
||||
// For other CCs, pacing delay is always 0
|
||||
Time now = Simulator::Now();
|
||||
auto pacing = Time(swift.m_pacing_delay);
|
||||
this->m_nextAvail = std::max(this->m_nextAvail, now + pacing);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
RdmaQueuePair::GetWin() const
|
||||
{
|
||||
|
|
|
@ -140,7 +140,7 @@ class RdmaQueuePair : public Object
|
|||
// previous cwnd
|
||||
double m_cwnd_prev;
|
||||
// time (nanosecond) of last Multiple Decrease
|
||||
uint64_t m_t_last_decrease;
|
||||
Time m_t_last_decrease;
|
||||
// pacing delay, i.e. sending interval
|
||||
uint64_t m_pacing_delay;
|
||||
// num of acked packets
|
||||
|
@ -190,6 +190,8 @@ class RdmaQueuePair : public Object
|
|||
// Determines if the number of packets on-the-fly has reached the congestion window limit,
|
||||
// indicating whether it's necessary to pause sending further packets.
|
||||
bool IsWinBound() const;
|
||||
// For Swift CC: update pacing delay (if exists)
|
||||
void UpdatePacing();
|
||||
// Calculates the current effective window size, potentially adjusting for variable window
|
||||
// algorithms or rate-based congestion control.
|
||||
uint64_t GetWin() const; // window size calculated from m_rate
|
||||
|
|
|
@ -454,21 +454,6 @@ SwitchNode::SwitchNotifyDequeue(uint32_t ifIndex, uint32_t qIndex, Ptr<Packet> p
|
|||
m_u[ifIndex] = newU;
|
||||
break;
|
||||
}
|
||||
// case SWIFT: {
|
||||
// CustomHeader ch;
|
||||
// if (ch.l3Prot != 0xfc)
|
||||
// { // only modify ack
|
||||
// std::cout << "l3proto=" << ch.l3Prot << ", skipping" << std::endl;
|
||||
// break;
|
||||
// }
|
||||
// // std::cout<<"Current hop: "<<ih->swift.nhop<<", uid:"<<p->GetUid()<<std::endl;
|
||||
// // hop + 1
|
||||
// ih->IncrementHop();
|
||||
// // std::cout<<"Current hop: "<<ih->swift.nhop<<", uid:"<<p->GetUid()<<std::endl;
|
||||
// std::cout << "Sniffed hop:" << ch.ack.ih.swift.nhop
|
||||
// << " Changed hop:" << ih->swift.nhop << std::endl;
|
||||
// break;
|
||||
// }
|
||||
default:
|
||||
FeedbackTag Int;
|
||||
bool found;
|
||||
|
@ -495,7 +480,7 @@ SwitchNode::SwitchNotifyDequeue(uint32_t ifIndex, uint32_t qIndex, Ptr<Packet> p
|
|||
case 0xfc: // ACK
|
||||
// I don't know why, got this offset by enumerating; this may not be the right
|
||||
// value!
|
||||
IntHeader* ih = (IntHeader*)&buf[PppHeader::GetStaticSize() + 20 + 4];
|
||||
IntHeader* ih = (IntHeader*)&buf[PppHeader::GetStaticSize() + 20 + 12];
|
||||
switch (m_ccMode)
|
||||
{
|
||||
case CC_MODE::SWIFT: {
|
||||
|
|
Loading…
Reference in New Issue