Commit 67f15d71 authored by rna's avatar rna
Browse files

Refactor BBR to use maximum payload size.

parent a08fa1d6
Loading
Loading
Loading
Loading
Loading
+20 −17
Original line number Diff line number Diff line
@@ -4,11 +4,10 @@
#include "receiver.h"
#include <math.h>


prrtByteCount_t BBR_Inflight(BBR* bbr, double gain)
{
    if (bbr->rtprop == Inf)
        return InitialCwnd; /* no valid RTT samples yet */
        return bbr->initial_cwnd; /* no valid RTT samples yet */
    uint32_t quanta = 0;
    uint32_t estimated_bdp = (uint32_t) round((((double)bbr->bw) * bbr->rtprop) / (1000 * 1000));
    return (uint32_t)(gain * estimated_bdp + quanta);
@@ -41,7 +40,7 @@ void BBR_CheckFullPipe(BBR* bbr, PrrtRateSample* rs)
{
    if (bbr->filled_pipe || !bbr->round_start || rs->is_app_limited)
        return;  // no need to check for a full pipe now
    if (bbr->bw >= bbr->full_bw * 1.25) {  // BBR.BtlBw still growing?
    if (bbr->bw >= bbr->full_bw * PROBE_GAIN) {  // BBR.BtlBw still growing?
        bbr->full_bw = bbr->bw;    // record new baseline level
        bbr->full_bw_count = 0;
        return;
@@ -58,14 +57,16 @@ bool BBR_IsNextCyclePhase(BBR* bbr, prrtByteCount_t bytes_lost, prrtByteCount_t
        return is_full_length;
    if (bbr->pacing_gain > 1)
        return is_full_length && (bytes_lost > 0 || prior_inflight >= BBR_Inflight(bbr, bbr->pacing_gain));
    return is_full_length || (prior_inflight <= BBR_Inflight(bbr, 1.0));
    bool is_max_length = (PrrtClock_get_current_time_us() - bbr->cycle_stamp) > 4 * bbr->rtprop;
    return is_max_length || (prior_inflight <= BBR_Inflight(bbr, 1.0));

}

void BBR_AdvanceCyclePhase(BBR* bbr)
{
    bbr->cycle_stamp = PrrtClock_get_current_time_us();
    bbr->cycle_index = (uint8_t )((bbr->cycle_index + 1) % BBRGainCycleLen);
    float pacing_gain_cycle[BBRGainCycleLen] = {1.25, 0.75, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0};
    float pacing_gain_cycle[BBRGainCycleLen] = {PROBE_GAIN, DRAIN_GAIN, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0};
    bbr->pacing_gain = pacing_gain_cycle[bbr->cycle_index];
    debug(DEBUG_BBR, "Advanced cycle with gain: %f", bbr->pacing_gain);
}
@@ -135,7 +136,7 @@ void BBR_HandleProbeRTT(BBR *bbr, PrrtPacketTracking *tracking) {
    tracking->app_limited = (tracking->delivered + tracking->pipe) ? : 1;
    /* Ignore low rate samples during ProbeRTT: */
    prrtTimestamp_t now = PrrtClock_get_current_time_us();
    if (bbr->probe_rtt_done_stamp == 0 && tracking->pipe <= BBRMinPipeCwnd) {
    if (bbr->probe_rtt_done_stamp == 0 && tracking->pipe <= bbr->min_pipe_cwnd) {
        bbr->probe_rtt_done_stamp = now + ProbeRTTDuration;
        bbr->probe_rtt_round_done = false;
        bbr->next_round_delivered = tracking->delivered;
@@ -183,13 +184,13 @@ void BBR_UpdateTargetCwnd(BBR* bbr)
void BBR_ModulateCwndForProbeRTT(BBR* bbr)
{
    if (bbr->state == PROBE_RTT)
        bbr->cwnd = MIN(bbr->cwnd, BBRMinPipeCwnd);
        bbr->cwnd = MIN(bbr->cwnd, bbr->min_pipe_cwnd);
}

void BBR_ModulateCwndForRecovery(BBR* bbr, prrtByteCount_t bytes_lost, prrtByteCount_t pipe, prrtByteCount_t delivered)
{
    if (bytes_lost > 0)
        bbr->cwnd = MAX(bbr->cwnd - bytes_lost, SMSS);
        bbr->cwnd = MAX(bbr->cwnd - bytes_lost, bbr->mps);
    if (bbr->packet_conservation)
        bbr->cwnd = MAX(bbr->cwnd, pipe + delivered);
}
@@ -202,9 +203,9 @@ void BBR_SetCwnd(BBR* bbr, PrrtPacketTracking* packetTracking)
    if (!bbr->packet_conservation) {
        if (bbr->filled_pipe)
            bbr->cwnd = MIN(bbr->cwnd + packetTracking->delivered, bbr->target_cwnd);
        else if (bbr->cwnd < bbr->target_cwnd || packetTracking->delivered < InitialCwnd)
        else if (bbr->cwnd < bbr->target_cwnd || packetTracking->delivered < bbr->initial_cwnd)
            bbr->cwnd = bbr->cwnd + packetTracking->delivered;
        bbr->cwnd = MAX(bbr->cwnd, BBRMinPipeCwnd);
        bbr->cwnd = MAX(bbr->cwnd, bbr->min_pipe_cwnd);
    }
    BBR_ModulateCwndForProbeRTT(bbr);
    debug(DEBUG_BBR, "New cwnd: %u, State: %u", bbr->cwnd, bbr->state);
@@ -226,9 +227,9 @@ void BBR_SetPacingRate(BBR* bbr)

void BBR_SetSendQuantum(BBR* bbr) {
    if(bbr->pacing_rate < 150000) { // 1.2Mbps = 0.15 MBps = 150000 Bps
        bbr->send_quantum = 1 * SMSS;
        bbr->send_quantum = 1 * bbr->mps;
    } else if (bbr->pacing_rate < 3000000) { // 24 Mbps = 20 * 1.2Mbps = 3000000
        bbr->send_quantum = 2 * SMSS;
        bbr->send_quantum = 2 * bbr->mps;
    } else {
        bbr->send_quantum = MIN((prrtByteCount_t) round((double) bbr->pacing_rate / 1000), 64000);
    }
@@ -270,7 +271,7 @@ void BBR_OnRTOLoss(BBR *bbr) {
    if(!bbr->is_loss_recovery) {
        bbr->is_loss_recovery = true;
        bbr->prior_cwnd = BBR_SaveCwnd(bbr);
        bbr->cwnd = SMSS;
        bbr->cwnd = bbr->mps;
    }
    check(pthread_mutex_unlock(&bbr->lock) == 0, "Unlock failed.");
    return;
@@ -291,7 +292,7 @@ void BBR_OnLossExit(BBR *bbr) {
    PERROR("BBR_OnACK failed.")
}

BBR* BBR_Init(void)
BBR* BBR_Init(prrtByteCount_t maximum_payload_size)
{
    BBR* bbr = calloc(1, sizeof(BBR));
    check_mem(bbr);
@@ -301,7 +302,9 @@ BBR* BBR_Init(void)
    check(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) == EXIT_SUCCESS, "Setting type failed.");
    check(pthread_mutex_init(&bbr->lock, &attr) == 0, "lock init failed.");


    bbr->mps = maximum_payload_size;
    bbr->min_pipe_cwnd = 4 * maximum_payload_size;
    bbr->initial_cwnd = 4 * maximum_payload_size;
    bbr->has_seen_rtt = false;
    bbr->btlBwFilter = WindowedFilter_Init(true);
    bbr->rtprop = Inf;
@@ -310,7 +313,7 @@ BBR* BBR_Init(void)
    bbr->probe_rtt_round_done = false;
    bbr->packet_conservation = false;
    bbr->prior_cwnd = 0;
    bbr->cwnd = InitialCwnd;
    bbr->cwnd = bbr->initial_cwnd;
    bbr->idle_restart = false;
    bbr->is_loss_recovery = false;

@@ -325,7 +328,7 @@ BBR* BBR_Init(void)
    bbr->full_bw_count = 0;

    //Init pacing rate
    double nominal_bandwidth = InitialCwnd / (bbr->has_seen_rtt ? bbr->rtprop : 1000);
    double nominal_bandwidth = bbr->initial_cwnd / (bbr->has_seen_rtt ? bbr->rtprop : 1000);
    bbr->pacing_rate = bbr->pacing_gain * nominal_bandwidth;

    BBR_EnterStartup(bbr);
+6 −4
Original line number Diff line number Diff line
@@ -10,12 +10,11 @@
#include "types/rateSample.h"
#include "../util/windowedFilter.h"

#define SMSS 1500
#define PROBE_GAIN 1.25
#define DRAIN_GAIN 0.75
#define RTpropFilterLen 10000000    //10s
#define BBRHighGain ((((float)2885) / 1000) + 1)
#define InitialCwnd (10 * SMSS)
#define BBRGainCycleLen 8
#define BBRMinPipeCwnd (4 * SMSS)
#define ProbeRTTDuration 200000 //200ms
#define Inf UINT32_MAX

@@ -29,6 +28,9 @@ enum bbr_state {
typedef struct bbr {
    pthread_mutex_t lock;

    prrtByteCount_t mps;
    prrtByteCount_t min_pipe_cwnd;
    prrtByteCount_t initial_cwnd;
    prrtTimedelta_t rtprop;
    prrtTimestamp_t rtprop_stamp;
    prrtTimestamp_t probe_rtt_done_stamp;
@@ -73,7 +75,7 @@ typedef struct bbr {
    WindowedFilter* btlBwFilter;
} BBR;

BBR* BBR_Init(void);
BBR* BBR_Init(prrtByteCount_t maximum_payload_size);
void BBR_OnACK(BBR* bbr, PrrtChannelStateInformation* csi, PrrtRateSample* rs, PrrtPacketTracking* packetTracking, prrtTimedelta_t rtt);
void BBR_OnSpuriousLoss(BBR *bbr, PrrtPacketTracking *tracking);
void BBR_OnRTOLoss(BBR *bbr);
+2 −2
Original line number Diff line number Diff line
@@ -98,7 +98,7 @@ bool update_and_generate_rate_sample(PrrtReceiver *recv, prrtSequenceNumber_t se
    return result;
}

PrrtReceiver *PrrtReceiver_create(const char *host, uint16_t port, prrtByteCount_t mss) {
PrrtReceiver *PrrtReceiver_create(const char *host, uint16_t port, prrtByteCount_t maximum_payload_size) {
    PrrtReceiver *recv = calloc(1, sizeof(PrrtReceiver));
    check_mem(recv);
    recv->host_name = strdup(host);
@@ -130,7 +130,7 @@ PrrtReceiver *PrrtReceiver_create(const char *host, uint16_t port, prrtByteCount
    check(0 == getaddrinfo(host, portstr, &hints, &info), "getaddrinfo");

    recv->ai = info;
    recv->bbr = BBR_Init();
    recv->bbr = BBR_Init(maximum_payload_size);

    pthread_mutexattr_t attr;
    check(pthread_mutexattr_init(&attr) == EXIT_SUCCESS, "Mutex attr init failed.");
+1 −1
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ typedef struct prrtReceiver {
    PrrtPacketTracking *packetTracking;
} PrrtReceiver;

PrrtReceiver *PrrtReceiver_create(const char *host, uint16_t port, prrtByteCount_t mss);
PrrtReceiver *PrrtReceiver_create(const char *host, uint16_t port, prrtByteCount_t maximum_payload_size);

void PrrtReceiver_add_outstanding_packet_state(PrrtReceiver *recv, PrrtPacket *packet, prrtTimestamp_t sentTime);
prrtByteCount_t PrrtReceiver_get_pipe(PrrtReceiver *recv);