Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add API to set BBR quantum ratio #1607

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 52 additions & 10 deletions picoquic/bbr.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,11 @@ typedef struct st_picoquic_bbr_state_t {
uint64_t loss_interval_start; /* Time in microsec when last loss considered */
uint64_t congestion_sequence; /* sequence number after congestion notification */
uint64_t cwin_before_suspension; /* So it can be restored if suspension stops. */

#if 1
uint64_t epoch_start_stamp;
#endif
uint64_t wifi_shadow_rtt; /* Shadow RTT used for wifi connections. */
double quantum_ratio; /* Fraction of pacing rate used for Quantum, or zero if not set*/
unsigned int filled_pipe : 1;
unsigned int round_start : 1;
unsigned int rt_prop_expired : 1;
Expand Down Expand Up @@ -330,17 +333,34 @@ void BBREnterStartup(picoquic_bbr_state_t* bbr_state)

void BBRSetSendQuantum(picoquic_bbr_state_t* bbr_state, picoquic_path_t* path_x)
{
if (bbr_state->pacing_rate < BBR_PACING_RATE_LOW) {
bbr_state->send_quantum = 1ull * path_x->send_mtu;
}
else if (bbr_state->pacing_rate < BBR_PACING_RATE_MEDIUM) {
bbr_state->send_quantum = 2ull * path_x->send_mtu;
if (bbr_state->quantum_ratio == 0) {
if (bbr_state->pacing_rate < BBR_PACING_RATE_LOW) {
bbr_state->send_quantum = 1ull * path_x->send_mtu;
}
else if (bbr_state->pacing_rate < BBR_PACING_RATE_MEDIUM) {
bbr_state->send_quantum = 2ull * path_x->send_mtu;
}
else {
bbr_state->send_quantum = (uint64_t)(bbr_state->pacing_rate * 0.001);
if (bbr_state->send_quantum > 0x10000) {
bbr_state->send_quantum = 0x10000;
}
}
}
else {
bbr_state->send_quantum = (uint64_t)(bbr_state->pacing_rate * 0.001);
bbr_state->send_quantum = (uint64_t)(bbr_state->pacing_rate * bbr_state->quantum_ratio);

if (bbr_state->send_quantum > 0x10000) {
bbr_state->send_quantum = 0x10000;
}
else if (bbr_state->send_quantum < 2ull * path_x->send_mtu) {
if (bbr_state->send_quantum < 1ull * path_x->send_mtu) {
bbr_state->send_quantum = 1ull * path_x->send_mtu;
}
else {
bbr_state->send_quantum = 2ull * path_x->send_mtu;
}
}
}
}

Expand All @@ -366,12 +386,14 @@ void BBRUpdateTargetCwnd(picoquic_bbr_state_t* bbr_state)
bbr_state->target_cwnd = BBRInflight(bbr_state, bbr_state->cwnd_gain);
}

static void picoquic_bbr_reset(picoquic_bbr_state_t* bbr_state, picoquic_path_t* path_x, uint64_t current_time, uint64_t wifi_shadow_rtt)
static void picoquic_bbr_reset(picoquic_bbr_state_t* bbr_state, picoquic_path_t* path_x, uint64_t current_time,
uint64_t wifi_shadow_rtt, double quantum_ratio)
{
memset(bbr_state, 0, sizeof(picoquic_bbr_state_t));
path_x->cwin = PICOQUIC_CWIN_INITIAL;
bbr_state->rt_prop = UINT64_MAX;
bbr_state->wifi_shadow_rtt = wifi_shadow_rtt;
bbr_state->quantum_ratio = quantum_ratio;

bbr_state->rt_prop_stamp = current_time;
bbr_state->cycle_stamp = current_time;
Expand All @@ -390,7 +412,7 @@ static void picoquic_bbr_init(picoquic_cnx_t * cnx, picoquic_path_t* path_x, uin

path_x->congestion_alg_state = (void*)bbr_state;
if (bbr_state != NULL) {
picoquic_bbr_reset(bbr_state, path_x, current_time, cnx->quic->wifi_shadow_rtt);
picoquic_bbr_reset(bbr_state, path_x, current_time, cnx->quic->wifi_shadow_rtt, cnx->quic->bbr_quantum_ratio);
}
}

Expand Down Expand Up @@ -532,6 +554,18 @@ void BBRltbwSampling(picoquic_bbr_state_t* bbr_state, picoquic_path_t* path_x, u
void BBRUpdateBtlBw(picoquic_bbr_state_t* bbr_state, picoquic_path_t* path_x, uint64_t current_time)
{
uint64_t bandwidth_estimate = path_x->bandwidth_estimate;
#if 1
if (path_x->delivered_last_packet >= bbr_state->next_round_delivered &&
bbr_state->epoch_start_stamp < current_time)
{
uint64_t delivered_this_round = path_x->delivered_last_packet - bbr_state->next_round_delivered;
uint64_t epoch_length = current_time - bbr_state->epoch_start_stamp;
uint64_t alt_estimate = delivered_this_round*1000000 / epoch_length;
if (alt_estimate > bandwidth_estimate) {
bandwidth_estimate = alt_estimate;
}
}
#endif

if (bbr_state->state == picoquic_bbr_alg_startup &&
bandwidth_estimate < (path_x->peak_bandwidth_estimate / 2)) {
Expand Down Expand Up @@ -559,6 +593,9 @@ void BBRUpdateBtlBw(picoquic_bbr_state_t* bbr_state, picoquic_path_t* path_x, ui
BBRltbwSampling(bbr_state, path_x, current_time);

if (bbr_state->round_start) {
#if 1
bbr_state->epoch_start_stamp = current_time;
#endif
if (bandwidth_estimate > bbr_state->btl_bw ||
!path_x->last_bw_estimate_path_limited) {
/* Forget the oldest BW round, shift by 1, compute the max BTL_BW for
Expand Down Expand Up @@ -608,6 +645,11 @@ void BBRUpdateRTprop(picoquic_bbr_state_t* bbr_state, uint64_t rtt_sample, uint6
if (20 * delta < bbr_state->rt_prop) {
bbr_state->rt_prop_stamp = current_time;
}
#if 1
if (bbr_state->rt_prop < 1000 && rtt_sample < 5000){
bbr_state->rt_prop_stamp = current_time;
}
#endif
}
}

Expand Down Expand Up @@ -1211,7 +1253,7 @@ static void picoquic_bbr_notify(
case picoquic_congestion_notification_cwin_blocked:
break;
case picoquic_congestion_notification_reset:
picoquic_bbr_reset(bbr_state, path_x, current_time, cnx->quic->wifi_shadow_rtt);
picoquic_bbr_reset(bbr_state, path_x, current_time, cnx->quic->wifi_shadow_rtt, cnx->quic->bbr_quantum_ratio);
break;
case picoquic_congestion_notification_seed_cwin:
if (bbr_state->state == picoquic_bbr_alg_startup_long_rtt) {
Expand Down
10 changes: 10 additions & 0 deletions picoquic/picoquic.h
Original file line number Diff line number Diff line change
Expand Up @@ -1453,6 +1453,16 @@ void picoquic_set_congestion_algorithm(picoquic_cnx_t* cnx, picoquic_congestion_
*/
void picoquic_set_default_wifi_shadow_rtt(picoquic_quic_t* quic, uint64_t wifi_shadow_rtt);

/* The experimental API `picoquic_set_default_bbr_quantum_ratio`
* allows application to change the "quantum ratio" parameter of the BBR
* algorithm. The default value is 0.001 (1/1000th of the pacing rate
* in bytes per second). Larger values like 0.01 would increase the
* size of the "leaky bucket" used by the pacing algorithms. Whether
* that's a good idea or not is debatable, probably depends on the
* application.
*/
void picoquic_set_default_bbr_quantum_ratio(picoquic_quic_t* quic, double quantum_ratio);

/* Bandwidth update and congestion control parameters value.
* Congestion control in picoquic is characterized by three values:
* - pacing rate, expressed in bytes per second (for example, 10Mbps would be noted as 1250000)
Expand Down
1 change: 1 addition & 0 deletions picoquic/picoquic_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,7 @@ typedef struct st_picoquic_quic_t {

picoquic_congestion_algorithm_t const* default_congestion_alg;
uint64_t wifi_shadow_rtt;
double bbr_quantum_ratio;

struct st_picoquic_cnx_t* cnx_list;
struct st_picoquic_cnx_t* cnx_last;
Expand Down
5 changes: 5 additions & 0 deletions picoquic/quicctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -4525,6 +4525,11 @@ void picoquic_set_default_wifi_shadow_rtt(picoquic_quic_t* quic, uint64_t wifi_s
quic->wifi_shadow_rtt = wifi_shadow_rtt;
}

void picoquic_set_default_bbr_quantum_ratio(picoquic_quic_t* quic, double quantum_ratio)
{
quic->bbr_quantum_ratio = quantum_ratio;
}

void picoquic_subscribe_pacing_rate_updates(picoquic_cnx_t* cnx, uint64_t decrease_threshold, uint64_t increase_threshold)
{
cnx->pacing_decrease_threshold = decrease_threshold;
Expand Down
Loading