github.com/geph-official/geph2@v0.22.6-0.20210211030601-f527cb59b0df/libs/kcp-go/kcp_bic.go (about)

     1  package kcp
     2  
     3  import (
     4  	"log"
     5  	"math"
     6  	"time"
     7  )
     8  
     9  const bicMultiplier = 1
    10  
    11  func (kcp *KCP) cubic_onloss(lost []uint32) {
    12  	kcp.wmax = kcp.cwnd
    13  	kcp.cwnd *= (2 - cubicB) / 2
    14  	kcp.lastLoss = time.Now()
    15  	if kcp.cwnd < 32 {
    16  		kcp.cwnd = 32
    17  	}
    18  	log.Println("wmax at", int(kcp.cwnd))
    19  }
    20  
    21  func (kcp *KCP) bic_onloss(lost []uint32) {
    22  	maxRun := 1
    23  	currRun := 0
    24  	lastSeen := uint32(0)
    25  	for _, v := range lost {
    26  		if v == lastSeen+1 {
    27  			currRun++
    28  			if maxRun < currRun {
    29  				maxRun = currRun
    30  			}
    31  		} else {
    32  			currRun = 0
    33  		}
    34  		lastSeen = v
    35  	}
    36  	// log.Println("lost with maxRun", maxRun)
    37  	// if maxRun < int(kcp.cwnd/20) || maxRun < 10 {
    38  	// 	return
    39  	// }
    40  	beta := 0.05 / bicMultiplier
    41  	if kcp.cwnd < kcp.wmax {
    42  		kcp.wmax = kcp.cwnd * (2.0 - beta) / 2.0
    43  	} else {
    44  		kcp.wmax = kcp.cwnd
    45  	}
    46  	kcp.cwnd = kcp.cwnd * (1.0 - beta)
    47  	mincwnd := kcp.bdp() / float64(kcp.mss)
    48  	if kcp.cwnd < mincwnd {
    49  		kcp.cwnd = mincwnd
    50  	}
    51  	if kcp.cwnd < 32 {
    52  		kcp.cwnd = 32
    53  	}
    54  }
    55  
    56  const (
    57  	cubicC = 100
    58  	cubicB = 0.5
    59  )
    60  
    61  func (kcp *KCP) cubic_onack(acks int32) {
    62  	if doLogging {
    63  		log.Printf("CUBIC cwnd=%v // t=%.2f%%", int(kcp.cwnd),
    64  			100*float64(kcp.retrans)/float64(kcp.trans))
    65  	}
    66  	for i := int32(0); i < acks; i++ {
    67  		t := time.Since(kcp.lastLoss).Seconds()
    68  		K := math.Pow(kcp.wmax*cubicB/cubicC, 1.0/3.0)
    69  		kcp.cwnd = math.Min(cubicC*math.Pow(t-K, 3)+kcp.wmax, kcp.cwnd+1)
    70  	}
    71  }
    72  
    73  func (kcp *KCP) bic_onack(acks int32) {
    74  	if doLogging {
    75  		log.Printf("BIC cwnd=%v // t=%.2f%%", int(kcp.cwnd),
    76  			100*float64(kcp.retrans)/float64(kcp.trans))
    77  	}
    78  
    79  	// // TCP BIC
    80  	for i := 0; i < int(acks*bicMultiplier); i++ {
    81  		var bicinc float64
    82  		if kcp.cwnd < kcp.wmax {
    83  			bicinc = (kcp.wmax - kcp.cwnd) / 2
    84  		} else {
    85  			bicinc = kcp.cwnd - kcp.wmax
    86  		}
    87  		if bicinc <= 1 {
    88  			bicinc = 1
    89  		} else {
    90  			if bicinc > 128 {
    91  				bicinc = 128
    92  			}
    93  		}
    94  		kcp.cwnd += bicinc / kcp.cwnd
    95  		if uint32(kcp.cwnd) > kcp.rmt_wnd {
    96  			kcp.cwnd = float64(kcp.rmt_wnd)
    97  		}
    98  	}
    99  	// if doLogging {
   100  	// 	log.Printf("BIC cwnd %.2f => %.2f [%.2f %%]", kcp.cwnd, kcp.wmax, float64(kcp.retrans)/float64(kcp.trans)*100)
   101  	// }
   102  	// kcp.cwnd += float64(acks) * kcp.aimd_multiplier()
   103  }