I have the rio implementation of Sean Murphy and James Scott.
http://www.teltec.dcu.ie/~murphys/ns-work/diffserv/index.html
http://www.aciri.org/ns/rio-ns2-1b6.tar.gz
However, there are differences in the algorithm's implementation. They both mark in packets according to in_v_ave, and out packets according to v_ave. However, their calculation of these variables (v_ave and in_v_ave) differs.
Sean calculates them on each packet enque. But James calculate in_v_ave and v_ave for each incoming **in** packet. And he calculates out_v_ave and v_ave for each **out** packet.
James calculates out_v_ave, but he never uses it. This is not important, but he updates the v_ave variable with both in_idle_ and idle_.
Can anyone tell me which algorithm is the correct one? Maybe I'm missing something, and they are both OK.
cheers,
below is the code from James's implementation:
For each in packet enque
int m = 0;
if (in_idle_) {
double now = Scheduler::instance().clock();
/* To account for the period when the queue was empty. */
in_idle_ = 0;
m = int(edp_.ptc * (now - in_idletime_));
}
run_in_estimator(qib_ ? in_bcount_ : in_len_,
qib_ ? bcount_ : q_->length(), m + 1);
-----------------------------------------For each out packet enque
int m = 0;
if (idle_) {
/* To account for the period when the queue was empty. */
idle_ = 0;
m = int(edp_.ptc * (now - idletime_));
}
// not sure whether this is correct, Yun
run_out_estimator(qib_ ? bcount_ - in_bcount_ : q_->length() - in_len_,
qib_ ? bcount_ : q_->length(), m + 1);
---------------------------------------------
void RIOQueue::run_in_estimator(int in_queued, int total_queued, int m)
{
in_f = (float)edv_.in_v_ave;
in_f_sl = (float)edv_.in_v_slope;
while (--m >= 1) {
in_f_old = in_f;
in_f *= 1.0 - (float)edp_.q_w;
total_f_old = total_f;
total_f *= 1.0 - (float)edp_.q_w;
}
in_f_old = in_f;
in_f *= 1.0 - (float)edp_.q_w;
in_f += (float)edp_.q_w * in_queued;
total_f_old = total_f;
total_f *= 1.0 - (float)edp_.q_w;
total_f += edp_.q_w * total_queued;
edv_.in_v_ave = in_f;
edv_.in_v_slope = in_f_sl;
edv_.v_ave = total_f;
edv_.v_slope = total_f_sl;
}
void bRIOQueue::run_out_estimator( int out_queued, int total_queued, int m)
{
total_f = edv_.v_ave;
total_f_sl = edv_.v_slope;
while (--m >= 1) {
out_f_old = out_f;
out_f *= 1.0 - edp_.q_w;
total_f_old = total_f;
total_f *= 1.0 - edp_.q_w;
}
out_f_old = out_f;
out_f *= 1.0 - edp_.q_w;
out_f += edp_.q_w * out_queued;
total_f_old = total_f;
total_f *= 1.0 - edp_.q_w;
total_f += edp_.q_w * total_queued;
edv_.out_v_ave = out_f;
edv_.out_v_slope = out_f_sl;
edv_.v_ave = total_f;
edv_.v_slope = total_f_sl;
}
******************************************************************
******************************************************************and here's Sean's implementation:
for each packet arrival, he calls this function:
void DSRIOPacketQueue::update_ewmas ()
{
// here we update the ewmas for the queue sizes. Here, we use the
// same approach as the RED stuff, except that here we don't
// get involved in byte level complications.
// in the RED implementation, the notion of a packet time
// constant is used. This assumes that there is some packet
// length that is average. I will assume this aswell.
int m=0;
if (idle_) {
double now = Scheduler::instance().clock();
/* To account for the period when the queue was empty. */
idle_ = false;
m = int(ptcinv * (now - idletime_));
}
while (--m >= 1) {
ewma_in *= 1.0 - q_weight_ ;
ewma_inout *= 1.0 - q_weight_ ;
}
ewma_in *= 1.0 - q_weight_;
ewma_inout *= 1.0 - q_weight_ ;
ewma_in += q_weight_ * curr_in_pkts;
ewma_inout += q_weight_ * get_packets_in_queue();
}
-- ___________________________________________________________________ Bahri OKUROGLU Software Design Engineer Nortel Networks, Netas R&D RT6 mailto:[email protected] http://www.netas.com.tr mailto:[email protected] http://www.nortelnetworks.com Nortel Networks, Netas Alemdag Cad. Umraniye 81244 ISTANBUL TURKEY ___________________________________________________________________