Compare commits

...

4 Commits

Author SHA1 Message Date
cyp0633 307a26ffa4
swift set sent time 2024-04-03 21:50:11 +08:00
cyp0633 6440cd3d29
swift packet pacing when cwnd<1 2024-04-03 21:49:44 +08:00
cyp0633 2138a091e7
swift intheader use u64 2024-04-03 21:47:26 +08:00
cyp0633 deb041ccc4
Add correct serialization to int header 2024-04-03 20:05:02 +08:00
9 changed files with 84 additions and 47 deletions

View File

@ -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;

View File

@ -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.
};

View File

@ -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
{

View File

@ -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
/**

View File

@ -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);

View File

@ -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)
{

View File

@ -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
{

View File

@ -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

View File

@ -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: {