void RUDPCCCObject::on_ack(uint64_t ack_seq) { if(ack_seq <= last_ack_id_) { return; } uint32_t space = (uint32_t)(ack_seq - last_ack_id_); if(slow_start_) //慢启动窗口决策 { snd_cwnd_ += space; if(snd_cwnd_ >= max_cwnd_) { slow_start_ = false; RUDP_INFO("ccc stop slow_start, snd_cwnd = " << snd_cwnd_); snd_cwnd_ = max_cwnd_; } RUDP_DEBUG("send window size = " << snd_cwnd_); } else //平衡状态 { if (recv_count_ / 2 < resend_count_) //出现丢包,不做加速 loss_flag_ = false; else if(resend_count_ == 0) //加速,快速恢复 { snd_cwnd_ = (uint32_t)(snd_cwnd_ + (snd_cwnd_ >> 3)); snd_cwnd_ = core_min(max_cwnd_, snd_cwnd_); loss_flag_ = false; } }
void DivRep::computeExactFlags() { if (!first->flagsComputed()) first->computeExactFlags(); if (!second->flagsComputed()) second->computeExactFlags(); if (!second->sign()) core_error("zero divisor.", __FILE__, __LINE__, true); if (!first->sign()) {// value must be exactly zero. reduceToZero(); return; } // rational node if (rationalReduceFlag) { if (first->ratFlag() > 0 && second->ratFlag() > 0) { BigRat val = (*(first->ratValue()))/(*(second->ratValue())); reduceToBigRat(val); ratFlag() = first->ratFlag() + second->ratFlag(); return; } else ratFlag() = -1; } // value is irrational. uMSB() = first->uMSB() - second->lMSB(); lMSB() = first->lMSB() - second->uMSB() - EXTLONG_ONE; sign() = first->sign() * second->sign(); extLong df = first->d_e(); extLong ds = second->d_e(); // extLong lf = first->length(); // extLong ls = second->length(); // length() = df * ls + ds * lf; measure() = (first->measure())*ds + (second->measure())*df; // BFMSS[2,5] bound. v2p() = first->v2p() + second->v2m(); v2m() = first->v2m() + second->v2p(); v5p() = first->v5p() + second->v5m(); v5m() = first->v5m() + second->v5p(); u25() = first->u25() + second->l25(); l25() = first->l25() + second->u25(); high() = first->high() + second->low(); low() = first->low() + second->high(); lc() = ds * first->lc() + df * second->tc(); tc() = core_min(ds * first->tc() + df * second->lc(), measure()); flagsComputed() = true; }
void DivRep::computeApproxValue(const extLong& relPrec, const extLong& absPrec) { if (lMSB() < EXTLONG_BIG && lMSB() > EXTLONG_SMALL) { extLong rr = relPrec + EXTLONG_SEVEN; // These rules come from extLong ra = uMSB() + absPrec + EXTLONG_EIGHT; // Koji's Master Thesis, page 65 extLong ra2 = core_max(ra, EXTLONG_TWO); extLong r = core_min(rr, ra2); extLong af = - first->lMSB() + r; extLong as = - second->lMSB() + r; extLong pr = relPrec + EXTLONG_SIX; extLong pa = uMSB() + absPrec + EXTLONG_SEVEN; extLong p = core_min(pr, pa); // Seems to be an error: // p can be negative here! // Also, this does not conform to // Koji's thesis which has a default // relative precision (p.65). appValue() = first->getAppValue(r, af).div(second->getAppValue(r, as), p); } else { std::cerr << "lMSB = " << lMSB() << std::endl; core_error("a huge lMSB in DivRep", __FILE__, __LINE__, false); } }
void RUDPCCCObject::on_timer(uint64_t now_ts) { uint32_t delay = core_max(rtt_ / 8, 50); if (now_ts >= prev_on_ts_ + delay) //10个RTT决策一次 { print_count_ ++; if(print_count_ % 4 == 0) { RUDP_DEBUG("send window size = " << snd_cwnd_ << ",rtt = " << rtt_ << ",rtt_var = " << rtt_var_ << ",resend = " << resend_count_); set_max_cwnd(rtt_); } if(slow_start_) //停止慢启动过程 { if(print_count_ > 10) { slow_start_ = false; RUDP_INFO("ccc stop slow_start, snd_cwnd = " << snd_cwnd_); } } else { if (recv_count_ > (snd_cwnd_ * delay * 7 / (rtt_ * 8))) { snd_cwnd_ = (uint32_t)(snd_cwnd_ + core_max(8,(snd_cwnd_ / 8))); snd_cwnd_ = core_min(max_cwnd_, snd_cwnd_); loss_flag_ = false; } else if (recv_count_ < snd_cwnd_ * delay * 5 / (rtt_ * 8)){ snd_cwnd_ = (uint32_t)(snd_cwnd_ - (snd_cwnd_ / 16)); snd_cwnd_ = core_max(min_cwnd_, snd_cwnd_); loss_flag_ = true; } else if (rtt_var_ > 30 && resend_count_ >= core_max(8, snd_cwnd_ * delay * 3 / (8 * rtt_))){ snd_cwnd_ = (uint32_t)(snd_cwnd_ - (snd_cwnd_ / 10)); snd_cwnd_ = core_max(min_cwnd_, snd_cwnd_); loss_flag_ = true; } resend_count_ = 0; } recv_count_ = 0; prev_on_ts_ = now_ts; } }
void RUDPRecvBuffer::on_timer(uint64_t now_timer, uint32_t rtc) { if(check_loss(now_timer, rtc)) { recv_new_packet_ = false; } uint32_t rtc_threshold = core_min(20, rtc / 2); if(last_ack_ts_ + rtc_threshold <= now_timer && recv_new_packet_) { net_channel_->send_ack(first_seq_); set_send_last_ack_ts(now_timer); } //判断是否可以读 if(!recv_data_.empty() && net_channel_ != NULL) net_channel_->on_read(); }
// Computes the root bit bound of the expression. // In effect, computeBound() returns the current value of low. extLong ExprRep::computeBound() { extLong measureBd = measure(); // extLong cauchyBd = length(); extLong ourBd = (d_e() - EXTLONG_ONE) * high() + lc(); // BFMSS[2,5] bound. extLong bfmsskBd; if (v2p().isInfty() || v2m().isInfty()) bfmsskBd = CORE_INFTY; else bfmsskBd = l25() + u25() * (d_e() - EXTLONG_ONE) - v2() - ceilLg5(v5()); // since we might compute \infty - \infty for this bound if (bfmsskBd.isNaN()) bfmsskBd = CORE_INFTY; extLong bd = core_min(measureBd, // core_min(cauchyBd, core_min(bfmsskBd, ourBd)); #ifdef CORE_SHOW_BOUNDS std::cout << "Bounds (" << measureBd << "," << bfmsskBd << ", " << ourBd << "), "; std::cout << "MIN = " << bd << std::endl; std::cout << "d_e= " << d_e() << std::endl; #endif #ifdef CORE_DEBUG_BOUND // Some statistics about which one is/are the winner[s]. computeBoundCallsCounter++; int number_of_winners = 0; std::cerr << " New contest " << std::endl; if (bd == bfmsskBd) { BFMSS_counter++; number_of_winners++; std::cerr << " BFMSS is the winner " << std::endl; } if (bd == measureBd) { Measure_counter++; number_of_winners++; std::cerr << " measureBd is the winner " << std::endl; } /* if (bd == cauchyBd) { Cauchy_counter++; number_of_winners++; std::cerr << " cauchyBd is the winner " << std::endl; } */ if (bd == ourBd) { LiYap_counter++; number_of_winners++; std::cerr << " ourBd is the winner " << std::endl; } assert(number_of_winners >= 1); if (number_of_winners == 1) { if (bd == bfmsskBd) { BFMSS_only_counter++; std::cerr << " BFMSSBd is the only winner " << std::endl; } else if (bd == measureBd) { Measure_only_counter++; std::cerr << " measureBd is the only winner " << std::endl; } /* else if (bd == cauchyBd) { Cauchy_only_counter++; std::cerr << " cauchyBd is the only winner " << std::endl; } */ else if (bd == ourBd) { LiYap_only_counter++; std::cerr << " ourBd is the only winner " << std::endl; } } #endif return bd; }//computeBound()
int main( int argc, char *argv[] ) { /* *************************************************************************** COMMAND LINE ARGUMENTS *************************************************************************** */ int eps = 54; // Number of bits of absolute precision desired // default to 54 bits (= machine double precision) int DOsqrt = 1; // a flag: defaults to 1 // (i.e., compute sqrt) int DOvalidate = 1; // a flag to validate Pi: defaults to 1 // (i.e., validate to 250 digits) if (argc > 1) eps = atoi(argv[1]); if (argc > 2) DOsqrt = atoi(argv[2]); if (argc > 3) { DOvalidate = atoi(argv[3]); if ((DOvalidate < 0) || (DOvalidate >2)) { std::cout << " !! Third argument in error, defaults to 1\n"; DOvalidate = 1; }; }; std::cout << "DOsqrt = " << DOsqrt << "; DOvalidate = " << DOvalidate << std::endl; /* *************************************************************************** COMPUTING Pi *************************************************************************** */ // Translates eps (in bits) to outputPrec (in digits) int outputPrec; // desired precision in digits outputPrec = (int) (eps * log(2.0)/log(10.0)); std::cout << " Output precision is " << outputPrec << " digits \n"; // Computing Auxilliary Values double t1 = arctan(5, eps + 6); // debugging output: // std::cout << std::setprecision(outputPrec+1) << "arctan(1/5) = " << t1 << std::endl; double t2 = arctan(239, eps + 4); // debugging output: // std::cout << std::setprecision(outputPrec+1) << "arctan(1/239) = " << t2 << std::endl; double pi = (4 * t1 - t2) * 4; pi.approx(CORE_posInfty, eps); // Output of Pi std::cout << " Pi = " << std::setprecision(outputPrec+1) << pi << std::endl; // Note: setprecision in C++ is actually "width" (=number of characters // in output. So we use "outputPrec + 1" to account for the decimal point. /* *************************************************************************** AUTOMATIC CHECK that (1) our internal value of Pi (2) our output value of Pi are both correct to 250 (or 2000) digits *************************************************************************** */ // Reading in digits of Pi from Files int prec = 0; // bit precision for the comparison std::ifstream from; // input stream from file if (DOvalidate == 0) { // no validation prec = 1; } if (DOvalidate == 1) { prec = core_min(eps, 830); // 830 bits = 250 digits. from.open("inputs/PI250", std::ios::in); // read 250 digits of Pi from file } if (DOvalidate == 2) { prec = core_min(eps, 6644); // 6644 bits = 2000 digits from.open("inputs/PI2000", std::ios::in); // read 2000 digits of Pi from file } if (DOvalidate > 0) { // validation needed std::string piStr; char c; while (from.get(c)) if ((c >= '0' && c <= '9') || (c=='.')) piStr += c; if (!from.eof()) std::cout << "!! Error in reading from PI250 \n"; from.close(); double bigPi(piStr.c_str()); // bigPi is the value of Pi from file // debug: // std::cout << " bigPi = " << std::setprecision(outputPrec + 1) << bigPi << std::endl; // CHECKING OUTPUT VALUE OF Pi: std::ostringstream ost; ost << std::setprecision(outputPrec+1) << pi << std::endl; piStr = ost.str(); // Need to take the min of outputPrec and the number of digits in bigPi int minPrec = 0; if (DOvalidate == 1) minPrec = core_min(outputPrec, 250); if (DOvalidate == 2) minPrec = core_min(outputPrec, 2000); double ee = pow(Expr(10), -minPrec+4); ee.approx(eps); std::cout << "pow(Expr(10), -minPrec+4)) = " << std::setprecision(outputPrec) << ee << std::endl; if ( fabs(Expr(piStr.c_str()) - bigPi) <= pow(Expr(10), -minPrec+4)) std::cout << " >> Output value of Pi verified to "<< minPrec << " digits\n"; else std::cout << " !! Output value of Pi INCORRECT to " << minPrec << " digits! \n"; // CHECKING INTERNAL VALUE of Pi: if ( fabs(pi - bigPi) <= (Expr)BigFloat::exp2(- prec +1)) std::cout << " >> Internal value of Pi verified up to " << prec << " bits\n"; else std::cout << " !! Internal value of Pi INCORRECT to " << prec << " bits! \n"; }; /* *************************************************************************** COMPUTING THE SQUARE ROOT of Pi to (eps - 2) bits of absolute precision *************************************************************************** */ if (DOsqrt == 0) return 0; // do not compute sqrt(Pi) // Here is sqrt(Pi) to 100 digits from Knuth: Expr SQRTPI="1.772453850905516027298167483341145182797549456122387128213807789852911284591032181374950656738544665"; double sPi = sqrt(pi); sPi.approx(CORE_posInfty, eps + 2); std::cout << " sqrt(Pi) = " << std::setprecision(outputPrec-1) << sPi << std::endl; /* *************************************************************************** AUTOMATIC CHECK that the internal value of computed sqrt(Pi) is correct up to the first 100 digits. *************************************************************************** */ prec = core_min(eps-1, 332); // 332 bits == 100 digits double d3 = fabs(sPi - SQRTPI); double tmp = pow(Expr(10), -(int) (prec * log(2.0)/log(10.0)) ); if ( d3 <= tmp ) std::cout << " >> Internal value of sqrt(Pi) verified to " << prec << " bits\n"; else std::cout << " !! Internal value of sqrt(Pi) INCORRECT to " << prec << " bits! \n"; return 0; }