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 ___________________________________________________________________