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
);
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 =
SCALING_CONSTANT
@ -16,34 +18,42 @@ float CUBIC::getCWnD(void) const {
+ _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 {
return _rtt_ema;
}
void CUBIC::onCongestion(void) {
const auto current_cwnd = getCWnD();
_time_point_reduction = getTimeNow();
_window_max = current_cwnd;
void CUBIC::addRTT(float new_delay) {
// lerp(new_delay, rtt_ema, 0.1)
_rtt_ema = RTT_EMA_ALPHA * new_delay + (1.f - RTT_EMA_ALPHA) * _rtt_ema;
//std::cout << "CONGESTION!\n";
}
size_t CUBIC::canSend(void) {
return 0;
}
std::vector<CUBIC::SeqIDType> CUBIC::getTimeouts(void) const {
return {};
}
void CUBIC::onSent(SeqIDType seq, size_t data_size) {
}
void CUBIC::onAck(std::vector<SeqIDType> seqs) {
}
void CUBIC::onLoss(SeqIDType seq, bool discard) {
const auto flow_space = FlowOnly::canSend();
if (flow_space == 0) {
return 0;
}
const int64_t cspace = getCWnD() - _in_flight_bytes;
if (cspace < MAXIMUM_SEGMENT_DATA_SIZE) {
return 0u;
}
// limit to whole packets
size_t space = std::ceil(cspace / MAXIMUM_SEGMENT_DATA_SIZE)
* MAXIMUM_SEGMENT_DATA_SIZE;
return std::min(space, flow_space);
}

View File

@ -1,11 +1,11 @@
#pragma once
#include "./cca.hpp"
#include "./flow_only.hpp"
#include <chrono>
struct CUBIC : public CCAI {
using clock = std::chrono::steady_clock;
struct CUBIC : public FlowOnly {
//using clock = std::chrono::steady_clock;
public: // config
static constexpr float BETA {0.7f};
@ -15,34 +15,22 @@ struct CUBIC : public CCAI {
private:
// window size before last reduciton
double _window_max {2.f * MAXIMUM_SEGMENT_SIZE}; // start with mss*2
double _window_last_max {2.f * MAXIMUM_SEGMENT_SIZE};
double _time_since_reduction {0.};
// 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;
//double _window_last_max {2.f * MAXIMUM_SEGMENT_SIZE};
double _time_point_reduction {getTimeNow()};
private:
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
// 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
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
// take time since last sent into account
@ -50,15 +38,15 @@ struct CUBIC : public CCAI {
size_t canSend(void) override;
// get the list of timed out seq_ids
std::vector<SeqIDType> getTimeouts(void) const override;
//std::vector<SeqIDType> getTimeouts(void) const override;
public: // callbacks
// 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
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()) {
// not next expected seq -> skip detected
// TODO: congestion event
std::cout << "CONGESTION out of order\n";
onCongestion();
//if (getTimeNow() >= _last_congestion_event + _last_congestion_rtt) {
//_recently_lost_data = true;
//_last_congestion_event = getTimeNow();
@ -95,6 +98,13 @@ void FlowOnly::onAck(std::vector<SeqIDType> seqs) {
// only mesure delay, if not a congestion
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>
struct FlowOnly : public CCAI {
using clock = std::chrono::steady_clock;
protected:
using clock = std::chrono::steady_clock;
public: // config
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
//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 {0.6f*1024*1024}; // 600MiB/s
float max_byterate_allowed {0.5f*1024*1024}; // 500MiB/s
//float max_byterate_allowed {0.6f*1024*1024}; // 600KiB/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.15f*1024*1024}; // 150KiB/s
private:
protected:
// initialize to low value, will get corrected very fast
float _fwnd {0.01f * max_byterate_allowed}; // in bytes
@ -32,7 +35,7 @@ struct FlowOnly : public CCAI {
clock::time_point _time_start_offset;
private:
protected:
// make values relative to algo start for readability (and precision)
// get timestamp in seconds
double getTimeNow(void) const {
@ -47,6 +50,8 @@ struct FlowOnly : public CCAI {
void updateWindow(void);
virtual void onCongestion(void) {};
public: // api
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
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;
}

View File

@ -6,8 +6,9 @@
#include <solanaceae/toxcore/tox_event_interface.hpp>
#include <solanaceae/ngc_ext/ngcext.hpp>
#include "./flow_only.hpp"
#include "./ledbat.hpp"
#include "./cubic.hpp"
//#include "./flow_only.hpp"
//#include "./ledbat.hpp"
#include "./rcv_buf.hpp"
#include "./snd_buf.hpp"
@ -140,7 +141,7 @@ class NGCFT1 : public ToxEventI, public NGCEXTEventI, public NGCFT1EventProvider
struct Group {
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 {
uint32_t file_kind;