in simulation/src/point-to-point/model/rdma-hw.cc [946:1105]
void RdmaHw::UpdateRateHp(Ptr<RdmaQueuePair> qp, Ptr<Packet> p, CustomHeader &ch, bool fast_react){
uint64_t next_seq = qp->snd_nxt;
bool print = !fast_react || true;
if (qp->hp.m_lastUpdateSeq == 0){ // first RTT
qp->hp.m_lastUpdateSeq = next_seq;
// store INT
IntHeader &ih = ch.ack.ih;
NS_ASSERT(ih.nhop <= IntHeader::maxHop);
for (uint32_t i = 0; i < ih.nhop; i++)
qp->hp.hop[i] = ih.hop[i];
#if PRINT_LOG
if (print){
printf("%lu %s %08x %08x %u %u [%u,%u,%u]", Simulator::Now().GetTimeStep(), fast_react? "fast" : "update", qp->sip.Get(), qp->dip.Get(), qp->sport, qp->dport, qp->hp.m_lastUpdateSeq, ch.ack.seq, next_seq);
for (uint32_t i = 0; i < ih.nhop; i++)
printf(" %u %lu %lu", ih.hop[i].GetQlen(), ih.hop[i].GetBytes(), ih.hop[i].GetTime());
printf("\n");
}
#endif
}else {
// check packet INT
IntHeader &ih = ch.ack.ih;
if (ih.nhop <= IntHeader::maxHop){
double max_c = 0;
bool inStable = false;
#if PRINT_LOG
if (print)
printf("%lu %s %08x %08x %u %u [%u,%u,%u]", Simulator::Now().GetTimeStep(), fast_react? "fast" : "update", qp->sip.Get(), qp->dip.Get(), qp->sport, qp->dport, qp->hp.m_lastUpdateSeq, ch.ack.seq, next_seq);
#endif
// check each hop
double U = 0;
uint64_t dt = 0;
bool updated[IntHeader::maxHop] = {false}, updated_any = false;
NS_ASSERT(ih.nhop <= IntHeader::maxHop);
for (uint32_t i = 0; i < ih.nhop; i++){
if (m_sampleFeedback){
if (ih.hop[i].GetQlen() == 0 && fast_react)
continue;
}
updated[i] = updated_any = true;
#if PRINT_LOG
if (print)
printf(" %u(%u) %lu(%lu) %lu(%lu)", ih.hop[i].GetQlen(), qp->hp.hop[i].GetQlen(), ih.hop[i].GetBytes(), qp->hp.hop[i].GetBytes(), ih.hop[i].GetTime(), qp->hp.hop[i].GetTime());
#endif
uint64_t tau = ih.hop[i].GetTimeDelta(qp->hp.hop[i]);;
double duration = tau * 1e-9;
double txRate = (ih.hop[i].GetBytesDelta(qp->hp.hop[i])) * 8 / duration;
double u = txRate / ih.hop[i].GetLineRate() + (double)std::min(ih.hop[i].GetQlen(), qp->hp.hop[i].GetQlen()) * qp->m_max_rate.GetBitRate() / ih.hop[i].GetLineRate() /qp->m_win;
#if PRINT_LOG
if (print)
printf(" %.3lf %.3lf", txRate, u);
#endif
if (!m_multipleRate){
// for aggregate (single R)
if (u > U){
U = u;
dt = tau;
}
}else {
// for per hop (per hop R)
if (tau > qp->m_baseRtt)
tau = qp->m_baseRtt;
qp->hp.hopState[i].u = (qp->hp.hopState[i].u * (qp->m_baseRtt - tau) + u * tau) / double(qp->m_baseRtt);
}
qp->hp.hop[i] = ih.hop[i];
}
DataRate new_rate;
int32_t new_incStage;
DataRate new_rate_per_hop[IntHeader::maxHop];
int32_t new_incStage_per_hop[IntHeader::maxHop];
if (!m_multipleRate){
// for aggregate (single R)
if (updated_any){
if (dt > qp->m_baseRtt)
dt = qp->m_baseRtt;
qp->hp.u = (qp->hp.u * (qp->m_baseRtt - dt) + U * dt) / double(qp->m_baseRtt);
max_c = qp->hp.u / m_targetUtil;
if (max_c >= 1 || qp->hp.m_incStage >= m_miThresh){
new_rate = qp->hp.m_curRate / max_c + m_rai;
new_incStage = 0;
}else{
new_rate = qp->hp.m_curRate + m_rai;
new_incStage = qp->hp.m_incStage+1;
}
if (new_rate < m_minRate)
new_rate = m_minRate;
if (new_rate > qp->m_max_rate)
new_rate = qp->m_max_rate;
#if PRINT_LOG
if (print)
printf(" u=%.6lf U=%.3lf dt=%u max_c=%.3lf", qp->hp.u, U, dt, max_c);
#endif
#if PRINT_LOG
if (print)
printf(" rate:%.3lf->%.3lf\n", qp->hp.m_curRate.GetBitRate()*1e-9, new_rate.GetBitRate()*1e-9);
#endif
}
}else{
// for per hop (per hop R)
new_rate = qp->m_max_rate;
for (uint32_t i = 0; i < ih.nhop; i++){
if (updated[i]){
double c = qp->hp.hopState[i].u / m_targetUtil;
if (c >= 1 || qp->hp.hopState[i].incStage >= m_miThresh){
new_rate_per_hop[i] = qp->hp.hopState[i].Rc / c + m_rai;
new_incStage_per_hop[i] = 0;
}else{
new_rate_per_hop[i] = qp->hp.hopState[i].Rc + m_rai;
new_incStage_per_hop[i] = qp->hp.hopState[i].incStage+1;
}
// bound rate
if (new_rate_per_hop[i] < m_minRate)
new_rate_per_hop[i] = m_minRate;
if (new_rate_per_hop[i] > qp->m_max_rate)
new_rate_per_hop[i] = qp->m_max_rate;
// find min new_rate
if (new_rate_per_hop[i] < new_rate)
new_rate = new_rate_per_hop[i];
#if PRINT_LOG
if (print)
printf(" [%u]u=%.6lf c=%.3lf", i, qp->hp.hopState[i].u, c);
#endif
#if PRINT_LOG
if (print)
printf(" %.3lf->%.3lf", qp->hp.hopState[i].Rc.GetBitRate()*1e-9, new_rate.GetBitRate()*1e-9);
#endif
}else{
if (qp->hp.hopState[i].Rc < new_rate)
new_rate = qp->hp.hopState[i].Rc;
}
}
#if PRINT_LOG
printf("\n");
#endif
}
if (updated_any)
ChangeRate(qp, new_rate);
if (!fast_react){
if (updated_any){
qp->hp.m_curRate = new_rate;
qp->hp.m_incStage = new_incStage;
}
if (m_multipleRate){
// for per hop (per hop R)
for (uint32_t i = 0; i < ih.nhop; i++){
if (updated[i]){
qp->hp.hopState[i].Rc = new_rate_per_hop[i];
qp->hp.hopState[i].incStage = new_incStage_per_hop[i];
}
}
}
}
}
if (!fast_react){
if (next_seq > qp->hp.m_lastUpdateSeq)
qp->hp.m_lastUpdateSeq = next_seq; //+ rand() % 2 * m_mtu;
}
}
}