cubic mostly working (simple), flow rtt seems funky ???

This commit is contained in:
Green Sky 2023-08-30 03:03:43 +02:00
parent d957f9496a
commit 0d49752c3e
No known key found for this signature in database
6 changed files with 72 additions and 58 deletions

View File

@ -8,7 +8,9 @@ float CUBIC::getCWnD(void) const {
(_window_max * (1. - BETA)) / SCALING_CONSTANT (_window_max * (1. - BETA)) / SCALING_CONSTANT
); );
const double TK = _time_since_reduction - K; const auto time_since_reduction = getTimeNow() - _time_point_reduction;
const double TK = time_since_reduction - K;
const double cwnd = const double cwnd =
SCALING_CONSTANT SCALING_CONSTANT
@ -16,34 +18,42 @@ float CUBIC::getCWnD(void) const {
+ _window_max + _window_max
; ;
std::cout << "K:" << K << " TK:" << TK << " cwnd:" << cwnd << " rtt:" << getCurrentDelay() << "\n"; std::cout
<< "K:" << K
<< " ts:" << time_since_reduction
<< " TK:" << TK
<< " cwnd:" << cwnd
<< " rtt:" << getCurrentDelay()
<< "\n"
;
return cwnd; return std::max<float>(cwnd, 2.f * MAXIMUM_SEGMENT_SIZE);
} }
float CUBIC::getCurrentDelay(void) const { void CUBIC::onCongestion(void) {
return _rtt_ema; const auto current_cwnd = getCWnD();
} _time_point_reduction = getTimeNow();
_window_max = current_cwnd;
void CUBIC::addRTT(float new_delay) { //std::cout << "CONGESTION!\n";
// lerp(new_delay, rtt_ema, 0.1)
_rtt_ema = RTT_EMA_ALPHA * new_delay + (1.f - RTT_EMA_ALPHA) * _rtt_ema;
} }
size_t CUBIC::canSend(void) { size_t CUBIC::canSend(void) {
const auto flow_space = FlowOnly::canSend();
if (flow_space == 0) {
return 0; return 0;
} }
std::vector<CUBIC::SeqIDType> CUBIC::getTimeouts(void) const { const int64_t cspace = getCWnD() - _in_flight_bytes;
return {}; if (cspace < MAXIMUM_SEGMENT_DATA_SIZE) {
} return 0u;
}
void CUBIC::onSent(SeqIDType seq, size_t data_size) {
} // limit to whole packets
size_t space = std::ceil(cspace / MAXIMUM_SEGMENT_DATA_SIZE)
void CUBIC::onAck(std::vector<SeqIDType> seqs) { * MAXIMUM_SEGMENT_DATA_SIZE;
}
return std::min(space, flow_space);
void CUBIC::onLoss(SeqIDType seq, bool discard) {
} }

View File

@ -1,11 +1,11 @@
#pragma once #pragma once
#include "./cca.hpp" #include "./flow_only.hpp"
#include <chrono> #include <chrono>
struct CUBIC : public CCAI { struct CUBIC : public FlowOnly {
using clock = std::chrono::steady_clock; //using clock = std::chrono::steady_clock;
public: // config public: // config
static constexpr float BETA {0.7f}; static constexpr float BETA {0.7f};
@ -15,34 +15,22 @@ struct CUBIC : public CCAI {
private: private:
// window size before last reduciton // window size before last reduciton
double _window_max {2.f * MAXIMUM_SEGMENT_SIZE}; // start with mss*2 double _window_max {2.f * MAXIMUM_SEGMENT_SIZE}; // start with mss*2
double _window_last_max {2.f * MAXIMUM_SEGMENT_SIZE}; //double _window_last_max {2.f * MAXIMUM_SEGMENT_SIZE};
double _time_since_reduction {0.}; double _time_point_reduction {getTimeNow()};
// initialize to low value, will get corrected very fast
float _fwnd {0.01f * max_byterate_allowed}; // in bytes
// rtt exponental moving average
float _rtt_ema {0.5f};
clock::time_point _time_start_offset;
private: private:
float getCWnD(void) const; float getCWnD(void) const;
// make values relative to algo start for readability (and precision)
// get timestamp in seconds
double getTimeNow(void) const {
return std::chrono::duration<double>{clock::now() - _time_start_offset}.count();
}
// moving avg over the last few delay samples // moving avg over the last few delay samples
// VERY sensitive to bundling acks // VERY sensitive to bundling acks
float getCurrentDelay(void) const; //float getCurrentDelay(void) const;
void addRTT(float new_delay); //void addRTT(float new_delay);
void onCongestion(void) override;
public: // api public: // api
CUBIC(size_t maximum_segment_data_size) : CCAI(maximum_segment_data_size) {} CUBIC(size_t maximum_segment_data_size) : FlowOnly(maximum_segment_data_size) {}
// TODO: api for how much data we should send // TODO: api for how much data we should send
// take time since last sent into account // take time since last sent into account
@ -50,15 +38,15 @@ struct CUBIC : public CCAI {
size_t canSend(void) override; size_t canSend(void) override;
// get the list of timed out seq_ids // get the list of timed out seq_ids
std::vector<SeqIDType> getTimeouts(void) const override; //std::vector<SeqIDType> getTimeouts(void) const override;
public: // callbacks public: // callbacks
// data size is without overhead // data size is without overhead
void onSent(SeqIDType seq, size_t data_size) override; //void onSent(SeqIDType seq, size_t data_size) override;
void onAck(std::vector<SeqIDType> seqs) override; //void onAck(std::vector<SeqIDType> seqs) override;
// if discard, not resent, not inflight // if discard, not resent, not inflight
void onLoss(SeqIDType seq, bool discard) override; //void onLoss(SeqIDType seq, bool discard) override;
}; };

View File

@ -86,6 +86,9 @@ void FlowOnly::onAck(std::vector<SeqIDType> seqs) {
if (it != _in_flight.begin()) { if (it != _in_flight.begin()) {
// not next expected seq -> skip detected // not next expected seq -> skip detected
// TODO: congestion event // TODO: congestion event
std::cout << "CONGESTION out of order\n";
onCongestion();
//if (getTimeNow() >= _last_congestion_event + _last_congestion_rtt) { //if (getTimeNow() >= _last_congestion_event + _last_congestion_rtt) {
//_recently_lost_data = true; //_recently_lost_data = true;
//_last_congestion_event = getTimeNow(); //_last_congestion_event = getTimeNow();
@ -95,6 +98,13 @@ void FlowOnly::onAck(std::vector<SeqIDType> seqs) {
// only mesure delay, if not a congestion // only mesure delay, if not a congestion
addRTT(now - std::get<1>(*it)); addRTT(now - std::get<1>(*it));
} }
} else {
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#if 0
// assume we got a duplicated packet
std::cout << "CONGESTION duplicate\n";
onCongestion();
#endif
} }
} }

View File

@ -7,19 +7,22 @@
#include <tuple> #include <tuple>
struct FlowOnly : public CCAI { struct FlowOnly : public CCAI {
protected:
using clock = std::chrono::steady_clock; using clock = std::chrono::steady_clock;
public: // config public: // config
static constexpr float RTT_EMA_ALPHA = 0.1f; // might need over time static constexpr float RTT_EMA_ALPHA = 0.1f; // might need over time
static constexpr float RTT_MAX = 2.f; // 2 sec is probably too much static constexpr float RTT_MAX = 2.f; // 2 sec is probably too much
//float max_byterate_allowed {100.f*1024*1024}; // 100MiB/s
float max_byterate_allowed {10.f*1024*1024}; // 10MiB/s
//float max_byterate_allowed {1.f*1024*1024}; // 1MiB/s //float max_byterate_allowed {1.f*1024*1024}; // 1MiB/s
//float max_byterate_allowed {0.6f*1024*1024}; // 600MiB/s //float max_byterate_allowed {0.6f*1024*1024}; // 600KiB/s
float max_byterate_allowed {0.5f*1024*1024}; // 500MiB/s //float max_byterate_allowed {0.5f*1024*1024}; // 500KiB/s
//float max_byterate_allowed {0.05f*1024*1024}; // 50KiB/s //float max_byterate_allowed {0.05f*1024*1024}; // 50KiB/s
//float max_byterate_allowed {0.15f*1024*1024}; // 150KiB/s //float max_byterate_allowed {0.15f*1024*1024}; // 150KiB/s
private: protected:
// initialize to low value, will get corrected very fast // initialize to low value, will get corrected very fast
float _fwnd {0.01f * max_byterate_allowed}; // in bytes float _fwnd {0.01f * max_byterate_allowed}; // in bytes
@ -32,7 +35,7 @@ struct FlowOnly : public CCAI {
clock::time_point _time_start_offset; clock::time_point _time_start_offset;
private: protected:
// make values relative to algo start for readability (and precision) // make values relative to algo start for readability (and precision)
// get timestamp in seconds // get timestamp in seconds
double getTimeNow(void) const { double getTimeNow(void) const {
@ -47,6 +50,8 @@ struct FlowOnly : public CCAI {
void updateWindow(void); void updateWindow(void);
virtual void onCongestion(void) {};
public: // api public: // api
FlowOnly(size_t maximum_segment_data_size) : CCAI(maximum_segment_data_size) {} FlowOnly(size_t maximum_segment_data_size) : CCAI(maximum_segment_data_size) {}

View File

@ -712,7 +712,7 @@ bool NGCFT1::onToxEvent(const Tox_Event_Group_Peer_Exit* e) {
} }
// reset cca // reset cca
peer.cca = std::make_unique<FlowOnly>(500-4); // TODO: replace with tox_group_max_custom_lossy_packet_length()-4 peer.cca = std::make_unique<CUBIC>(500-4); // TODO: replace with tox_group_max_custom_lossy_packet_length()-4
return false; return false;
} }

View File

@ -6,8 +6,9 @@
#include <solanaceae/toxcore/tox_event_interface.hpp> #include <solanaceae/toxcore/tox_event_interface.hpp>
#include <solanaceae/ngc_ext/ngcext.hpp> #include <solanaceae/ngc_ext/ngcext.hpp>
#include "./flow_only.hpp" #include "./cubic.hpp"
#include "./ledbat.hpp" //#include "./flow_only.hpp"
//#include "./ledbat.hpp"
#include "./rcv_buf.hpp" #include "./rcv_buf.hpp"
#include "./snd_buf.hpp" #include "./snd_buf.hpp"
@ -140,7 +141,7 @@ class NGCFT1 : public ToxEventI, public NGCEXTEventI, public NGCFT1EventProvider
struct Group { struct Group {
struct Peer { struct Peer {
std::unique_ptr<CCAI> cca = std::make_unique<FlowOnly>(500-4); // TODO: replace with tox_group_max_custom_lossy_packet_length()-4 std::unique_ptr<CCAI> cca = std::make_unique<CUBIC>(500-4); // TODO: replace with tox_group_max_custom_lossy_packet_length()-4
struct RecvTransfer { struct RecvTransfer {
uint32_t file_kind; uint32_t file_kind;